/**
 @file sys_usw_queue_enq.c

 @date 2010-01-13

 @version v2.0

*/

/****************************************************************************
 *  Default Queue Mode
 *
 *           type          port id    QSelType     queue number    Enqueue Param
 *     ----------------  ----------   ---------   ------------    --------------
 *      network egress     0 - 47      0            16 * 48       Based on Channel Id
 *      drop port          48          0            16            Based on Channel Id
 *      RX OAM             55          0            16            Based on RxOamType
 *      Reserved port      56 - 63     0            16*8          Based on Channel Id
        exception to cpu   49 (DMA)    1            128           Based on SubQueId
        exception to cpu   50 (ETH)    1            16            Based on SubQueId(share network egress queue)
*********************************************************************************/

/****************************************************************************
 *
 * Header Files
 *
 ****************************************************************************/

#include "ctc_debug.h"
#include "ctc_const.h"
#include "ctc_error.h"
#include "ctc_macro.h"
#include "ctc_vector.h"
#include "ctc_linklist.h"
#include "ctc_qos.h"
#include "ctc_warmboot.h"

#include "sys_usw_common.h"
#include "sys_usw_opf.h"
#include "sys_usw_internal_port.h"
#include "sys_usw_stats_api.h"
#include "sys_usw_dma.h"

#include "sys_usw_qos.h"
#include "sys_usw_nexthop_api.h"
#include "sys_usw_port_api.h"
#include "sys_usw_l2_fdb.h"
#include "sys_usw_dmps.h"
#include "sys_usw_stats.h"
#include "sys_usw_register.h"
#include "sys_usw_wb_common.h"

#include "drv_api.h"

/****************************************************************************
 *
 * Global and Declaration
 *
 ****************************************************************************/

#define SYS_QUEUE_HASH_MAX   256
#define SYS_QUEUE_HASH_BLOCK_SIZE 8
#define SYS_QUEUE_HASH_BLOCK_NUM (SYS_QUEUE_HASH_MAX + (SYS_QUEUE_HASH_BLOCK_SIZE - 1) / SYS_QUEUE_HASH_BLOCK_SIZE)

#define SYS_SERVICE_HASH_MAX   2048
#define SYS_SERVICE_HASH_BLOCK_SIZE 16
#define SYS_SERVICE_HASH_BLOCK_NUM (SYS_SERVICE_HASH_MAX / SYS_SERVICE_HASH_BLOCK_SIZE)

#define SYS_QOS_QUEUE_ENQ_REP_QUEUE_SELECT_MAX  1

#define SYS_QOS_QUEUE_HW_CTL_QUEUE_SPAN     0
#define SYS_QOS_QUEUE_HW_CTL_QUEUE_MC       1
#define SYS_QOS_QUEUE_HW_CTL_QUEUE_CPU      2
#define SYS_QOS_QUEUE_HW_CTL_QUEUE_C2C      3


#define SYS_QOS_QUEUE_SW_CTL_QUEUE_C2C_0      9 /*enq_mode 0*/
#define SYS_QOS_QUEUE_SW_CTL_QUEUE_MC_1       8  /*enq_mode 1*/
#define SYS_QOS_QUEUE_SW_CTL_QUEUE_SPAN_1     9  /*enq_mode 1*/
#define SYS_QOS_QUEUE_SW_CTL_QUEUE_CPU_1      10 /*enq_mode 1*/
#define SYS_QOS_QUEUE_SW_CTL_QUEUE_C2C_1      11 /*enq_mode 1*/
#define SYS_QOS_QUEUE_SW_CTL_QUEUE_CPU_2      8  /*enq_mode 0/2*/
#define SYS_QOS_QUEUE_SW_CTL_QUEUE_SPAN_2     9  /*enq_mode 2*/
#define SYS_QOS_QUEUE_SW_CTL_QUEUE_C2C_2      10 /*enq_mode 2*/


#define SYS_QOS_QUEUE_NORMAL_EXCP_TYPE_EPE_OTHER 192
#define SYS_QOS_QUEUE_NORMAL_EXCP 0

#define SYS_QOS_QUEUE_ENQ_SERVICE_ID_WIDTH     9
#define SYS_QOS_QUEUE_ENQ_LOGIC_PORT_WIDTH     16
#define SYS_QOS_QUEUE_ENQ_NH_OFFSET_WIDTH      18
#define SYS_QOS_QUEUE_ENQ_NH_OFFSET_WIDTH_FIX  8

#define SYS_QOS_QUEUE_NH_OFFSET_OR_LOGIC_PORT_ENQ_SHIFT 31

#define ABS(n) ((((int32)(n)) < 0) ? -(n) : (n))


#define SYS_QOS_RX_DMA_CHANNEL(excp_group) {\
   if (p_usw_queue_master[lchip]->max_dma_rx_num == 4)\
   {\
      if (excp_group < 4) \
  	  {\
  	     channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0);\
  	  }\
      else if (excp_group < 8)\
      {\
          channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX1);\
      }\
      else if (excp_group < 12)\
      {\
         channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX2);\
      }\
      else\
      {\
         channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX3);\
      }\
   }\
   else if (p_usw_queue_master[lchip]->max_dma_rx_num == 2)\
   {\
      if (excp_group < 8) \
  	  {\
  	     channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0);\
  	  }\
      else\
      {\
          channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX1);\
      }\
   }\
   else if (p_usw_queue_master[lchip]->max_dma_rx_num == 1)\
   {\
     channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0);\
   }  \
}

sys_queue_master_t* p_usw_queue_master[CTC_MAX_LOCAL_CHIP_NUM_PP] = {NULL};
uint32
_sys_usw_qos_unbind_service_dstport(uint8 lchip, uint32 service_id, uint32 dest_port, uint16 logic_port, uint8 dir, uint8 offset, uint16 service_flag);
int32
_sys_usw_qos_add_update_group_id_to_channel(uint8 lchip, uint16 group_id, uint8 channel, uint8 flag);
int32
_sys_usw_queue_alloc_ext_group(uint8 lchip, uint32 num, uint8 multi, uint32* group_id);
int32
_sys_usw_queue_free_ext_group(uint8 lchip, uint32 num, uint32 group_id);

extern char*
sys_usw_reason_2Str(uint16 reason_id);

/****************************************************************************
 *
 * Function
 *
 ****************************************************************************/
uint32
sys_usw_logicport_service_hash_make(sys_qos_logicport_service_t* p_node)
{
    uint32 data[1] = {0};
    uint32 length = 0;
    data[0] = p_node->logic_src_port;
    length = sizeof(uint16);
    return ctc_hash_caculate(length, (uint8*)data);
}
bool
sys_usw_logicport_service_hash_cmp(sys_qos_logicport_service_t* p_node0,sys_qos_logicport_service_t* p_node1)
{
    if (p_node0->logic_src_port == p_node1->logic_src_port)
    {
        return TRUE;
    }
    return FALSE;
}
sys_qos_logicport_service_t*
sys_usw_logicport_service_lookup(uint8 lchip, sys_qos_logicport_service_t* p_node)
{
    return ctc_hash_lookup(p_usw_queue_master[lchip]->p_logicport_service_hash, p_node);
}
sys_qos_logicport_service_t*
sys_usw_logicport_service_add(uint8 lchip, sys_qos_logicport_service_t* p_node)
{


    return ctc_hash_insert(p_usw_queue_master[lchip]->p_logicport_service_hash, p_node);
}
sys_qos_logicport_service_t*
sys_usw_logicport_service_remove(uint8 lchip, sys_qos_logicport_service_t* p_node)
{
    return ctc_hash_remove(p_usw_queue_master[lchip]->p_logicport_service_hash, p_node);
}
uint32
sys_usw_service_hash_make(sys_service_node_t* p_node)
{
    uint32 data[1] = {0};
    uint32 length = 0;
    data[0] = p_node->service_id;
    length = sizeof(uint32)*1;
    return ctc_hash_caculate(length, (uint8*)data);
}
bool
sys_usw_service_hash_cmp(sys_service_node_t* p_node0,sys_service_node_t* p_node1)
{
    if (p_node0->service_id == p_node1->service_id)
    {
        return TRUE;
    }
    return FALSE;
}
sys_service_node_t*
sys_usw_service_lookup(uint8 lchip, sys_service_node_t* p_node)
{
    return ctc_hash_lookup(p_usw_queue_master[lchip]->p_service_hash, p_node);
}
sys_service_node_t*
sys_usw_service_add(uint8 lchip, sys_service_node_t* p_node)
{
    return ctc_hash_insert(p_usw_queue_master[lchip]->p_service_hash, p_node);
}
sys_service_node_t*
sys_usw_service_remove(uint8 lchip, sys_service_node_t* p_node)
{
    return ctc_hash_remove(p_usw_queue_master[lchip]->p_service_hash, p_node);
}
STATIC int32
_sys_usw_queue_vec_free_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_hash_free_node_data(void* node_data, void* user_data)
{
    mem_free(node_data);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_hash_free_list_node_data(void* node_data, void* user_data)
{
    sys_service_node_t* p_service = (sys_service_node_t*)node_data;
    ctc_slistnode_t *node, *next_node;
    sys_qos_destport_t* p_dest_port_node = NULL;
    sys_qos_logicport_t* p_logic_port_node = NULL;

    CTC_SLIST_LOOP_DEL(p_service->p_logic_port_list, node,next_node)
    {
        p_logic_port_node = _ctc_container_of(node, sys_qos_logicport_t, head);
        mem_free(p_logic_port_node);
    }

    CTC_SLIST_LOOP_DEL(p_service->p_dest_port_list, node,next_node)
    {
        p_dest_port_node = _ctc_container_of(node, sys_qos_destport_t, head);
        mem_free(p_dest_port_node);
    }

    ctc_slist_free(p_service->p_logic_port_list);
    ctc_slist_free(p_service->p_dest_port_list);

    mem_free(node_data);

    return CTC_E_NONE;
}


uint32
sys_usw_port_extender_hash_make(sys_extend_que_node_t* p_node)
{
    uint8* data = (uint8*)(p_node);
    uint8  length = sizeof(sys_extend_que_node_t) - sizeof(uint32)*4;

    return ctc_hash_caculate(length, data);
}

bool
sys_usw_port_extender_hash_cmp(sys_extend_que_node_t* p_node0,
                                  sys_extend_que_node_t* p_node1)
{
    if (p_node0->lchip == p_node1->lchip &&
        p_node0->lport == p_node1->lport &&
        p_node0->channel == p_node1->channel &&
        p_node0->type == p_node1->type &&
        p_node0->service_id == p_node1->service_id &&
        p_node0->logic_src_port == p_node1->logic_src_port&&
        p_node0->dir == p_node1->dir)
    {
        return TRUE;
    }

    return FALSE;
}

sys_extend_que_node_t*
sys_usw_port_extender_lookup(uint8 lchip, sys_extend_que_node_t* p_node)
{
    return ctc_hash_lookup(p_usw_queue_master[lchip]->p_port_extender_hash, p_node);
}

int32
sys_usw_port_extender_add(uint8 lchip, sys_extend_que_node_t* p_node)
{
    if (NULL == ctc_hash_insert(p_usw_queue_master[lchip]->p_port_extender_hash, p_node))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }

    return CTC_E_NONE;
}

int32
sys_usw_port_extender_remove(uint8 lchip, sys_extend_que_node_t* p_node)
{
    ctc_hash_remove(p_usw_queue_master[lchip]->p_port_extender_hash, p_node);

    return CTC_E_NONE;
}

int32
_sys_usw_qos_create_service(uint8 lchip, uint32 service_id)
{
    CTC_MIN_VALUE_CHECK(service_id, 1);
    if(p_usw_queue_master[lchip]->service_queue_mode == 0 || p_usw_queue_master[lchip]->service_queue_mode == 2)
    {
        sys_service_node_t* p_service = NULL;
        sys_service_node_t service;

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
        sal_memset(&service, 0, sizeof(service));
        service.service_id = service_id;
        p_service = sys_usw_service_lookup(lchip, &service);
        if (NULL != p_service)
        {
            return CTC_E_ENTRY_EXIST;
        }
        p_service =  mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_service_node_t));
        if (NULL == p_service)
        {
            return CTC_E_NO_MEMORY;
        }
        sal_memset(p_service, 0, sizeof(sys_service_node_t));
        p_service->service_id= service_id;
        p_service->p_logic_port_list = ctc_slist_new();
        if (p_service->p_logic_port_list == NULL)
        {
            mem_free(p_service);
            return CTC_E_NO_MEMORY;
        }
        p_service->p_dest_port_list = ctc_slist_new();
        if (p_service->p_dest_port_list == NULL)
        {
            ctc_slist_free(p_service->p_logic_port_list);
            mem_free(p_service);
            return CTC_E_NO_MEMORY;
        }
        sys_usw_service_add(lchip, p_service);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT, 1);
    }

    return CTC_E_NONE;

}

int32
_sys_usw_qos_destroy_service(uint8 lchip, uint32 service_id)
{
    CTC_MIN_VALUE_CHECK(service_id, 1);
    if(p_usw_queue_master[lchip]->service_queue_mode == 0 || p_usw_queue_master[lchip]->service_queue_mode == 2)
    {
        uint8 gchip = 0;
        uint16 dest_port = 0;
        sys_service_node_t* p_service = NULL;
        sys_service_node_t service;
        sys_qos_destport_t *p_dest_port_node = NULL;
        ctc_slistnode_t *ctc_slistnode = NULL;
        ctc_slistnode_t *ctc_slistnode_new = NULL;

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
        CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
        sal_memset(&service, 0, sizeof(service));
        service.service_id = service_id;
        p_service = sys_usw_service_lookup(lchip, &service);
        if (NULL == p_service)
        {
            return CTC_E_NOT_EXIST;
        }
        /*1.check logic port is NULL*/
        if(!CTC_LIST_ISEMPTY(p_service->p_logic_port_list))
        {
            return CTC_E_INVALID_PARAM;
        }
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT, 1);
        /*2.unbind all destport queue*/
        CTC_SLIST_LOOP_DEL(p_service->p_dest_port_list, ctc_slistnode, ctc_slistnode_new)
        {
            p_dest_port_node = _ctc_container_of(ctc_slistnode, sys_qos_destport_t, head);
            dest_port = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip,p_dest_port_node->lport);
            _sys_usw_qos_unbind_service_dstport(p_dest_port_node->lchip,service_id,dest_port,0,CTC_INGRESS,0,0);
        }
        sys_usw_service_remove(lchip, p_service);

        ctc_slist_free(p_service->p_logic_port_list);
        ctc_slist_free(p_service->p_dest_port_list);

        mem_free(p_service);
    }
    return CTC_E_NONE;
}

int32 sys_usw_qos_get_mux_port_enable(uint8 lchip, uint32 gport, uint8* enable)
{
    uint16 channel = 0xFF;
    uint32 cmd = 0;
    uint32 field_val =0;

    _sys_usw_get_channel_by_port(lchip, gport, &channel);
    if (!SYS_IS_NETWORK_CHANNEL(channel))
    {
        return CTC_E_NONE;
    }

    cmd = DRV_IOR(IpePhyPortMuxCtl_t, IpePhyPortMuxCtl_muxType_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));
    /*SYS_STK_MUX_TYPE_HDR_REGULAR_PORT     = 0,  4'b0000: Regular port(No MUX)
      SYS_STK_MUX_TYPE_HDR_WITHOUT_TUNNEL   = 6,   4'b0110: BridgeHeader without tunnel
      #define MUXTYPE_MUXDEMUX                         "1"
      #define MUXTYPE_EVB                              "2"
      #define MUXTYPE_CB_DOWNLINK                      "3"
      #define MUXTYPE_PE_DOWNLINK_WITH_CASCADE_PORT    "4"
      #define MUXTYPE_PE_UPLINK                        "5"*/
    if (field_val >= 5 || field_val == 0)
    {
        *enable = 0;
    }
    else
    {
        *enable = !!p_usw_queue_master[lchip]->queue_num_per_extend_port;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_get_stacking_enable(uint8 lchip, uint8 chan, uint8* enable)
{
    uint32 cmd                     = 0;
    uint32 packet_header_en[8]     = {0};
    uint8 chan_tmp = SYS_USW_CHANNEL_ENCODE(chan); /* for TMG, chan bit7 is dpid, bit6 is not use */
    EpeHdrAdjustChanCtl_m    epe_hdr_adjust_chan_ctl;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if (!SYS_IS_NETWORK_CHANNEL(chan_tmp))
    {
        return CTC_E_NONE;
    }
    sal_memset(&epe_hdr_adjust_chan_ctl, 0, sizeof(epe_hdr_adjust_chan_ctl));
    cmd = DRV_IOR(EpeHdrAdjustChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_hdr_adjust_chan_ctl));
    GetEpeHdrAdjustChanCtl(A, packetHeaderEn_f, &epe_hdr_adjust_chan_ctl, packet_header_en);

    *enable = CTC_IS_BIT_SET(packet_header_en[chan_tmp >> 5], chan_tmp & 0x1F) && SYS_C2C_QUEUE_MODE(lchip);

    return CTC_E_NONE;
}

int32
_sys_usw_queue_get_ext_queue_enable(uint8 lchip, uint32 gport, uint8* stacking_queue_en,
                                                     uint8* bpe_en, uint32* dot1ae_en, uint8* ext_que_en)
{
    uint16 channel = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    _sys_usw_get_channel_by_port(lchip, gport, &channel);
    _sys_usw_queue_get_stacking_enable(lchip, channel, stacking_queue_en);
    sys_usw_qos_get_mux_port_enable(lchip, gport, bpe_en);
    /*sys_usw_port_get_direction_property(lchip, gport, CTC_PORT_DIR_PROP_DOT1AE_EN, CTC_EGRESS, dot1ae_en);*/

    *ext_que_en = *stacking_queue_en || *bpe_en || *dot1ae_en;

    return CTC_E_NONE;
}

/*
 get ext queue id
*/
int32
_sys_usw_queue_get_ext_queue_id(uint8 lchip, ctc_qos_queue_id_t* p_queue,
                                  uint16* queue_id)
{
    uint16 channel = 0;
    uint16 lport = 0;
    uint32 dot1ae_en = 0;
    uint8 dot1ae_enq_chan = 0;
    uint8 stacking_queue_en = 0;
    uint8 bpe_en = 0;
    uint8 ext_que_en = 0;
    uint16 group_id = 0;
    uint8 type = 0;
    uint16 queue_base = 0;
    sys_extend_que_node_t extend_que_node;
    sys_extend_que_node_t* p_extend_que_node = NULL;
    sal_memset(&extend_que_node, 0, sizeof(sys_extend_que_node_t));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    _sys_usw_get_channel_by_port(lchip, p_queue->gport, &channel);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_queue->gport, lchip, lport);
    _sys_usw_queue_get_ext_queue_enable(lchip, p_queue->gport, &stacking_queue_en, &bpe_en, &dot1ae_en, &ext_que_en);
    /*CTC_ERROR_RETURN(sys_usw_datapath_get_dot1ae_enq_chan(lchip, &dot1ae_enq_chan));
    */
    if (dot1ae_en)
    {
        channel = dot1ae_enq_chan;
    }

    if (stacking_queue_en)
    {
        type = SYS_EXTEND_QUE_TYPE_C2C;
    }
    else
    {
        type = SYS_EXTEND_QUE_TYPE_BPE;
        extend_que_node.lport = lport;
    }

    extend_que_node.type = type;
    extend_que_node.lchip = lchip;
    extend_que_node.channel = channel;
    p_extend_que_node = sys_usw_port_extender_lookup(lchip, &extend_que_node);
    if (NULL == p_extend_que_node && (stacking_queue_en && p_queue->queue_id >= p_usw_queue_master[lchip]->queue_num_per_chanel))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    group_id = p_extend_que_node ? p_extend_que_node->group_id : 0;

    if (bpe_en || dot1ae_en)
    {
        CTC_MAX_VALUE_CHECK(p_queue->queue_id, p_usw_queue_master[lchip]->queue_num_per_extend_port - 1);

        if (DRV_FROM_TMM(lchip))
        {
            if (group_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_GRP_BASE_16Q))
            {
                queue_base = group_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP);
            }
            else
            {
                queue_base = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_16Q) + (group_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_GRP_BASE_16Q)) * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP_16Q);
            }
        }
        else
        {
            queue_base = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) + group_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
        }

        *queue_id = queue_base + p_queue->queue_id;
    }
    else if (stacking_queue_en) /* enq_mode 0:8(uc+mc)+1(cpu)+8(c2c)/1(C2C uc), enq_mode 1:8(uc)+1(mc)+1(log)+1(cpu)+8(c2c)/1(C2C uc), enq_mode 2:8(uc)+1(log)+1(cpu)+8(c2c)/1(C2C uc)*/
    {
        CTC_MAX_VALUE_CHECK(p_queue->queue_id, p_usw_queue_master[lchip]->queue_num_per_chanel + (p_usw_queue_master[lchip]->queue_num_per_stk_port == 1 ? 0 : SYS_C2C_QUEUE_NUM) - 1);
        if (p_queue->queue_id >= 8)
        {
            if (DRV_FROM_TMM(lchip))
            {
                if (group_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_GRP_BASE_16Q))
                {
                    queue_base = group_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP);
                }
                else
                {
                    queue_base = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_16Q) + (group_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_GRP_BASE_16Q)) * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP_16Q);
                }
            }
            else
            {
                queue_base = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) + group_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
            }
            *queue_id = queue_base + (p_queue->queue_id % p_usw_queue_master[lchip]->queue_num_per_chanel);
            if (p_usw_queue_master[lchip]->enq_mode == 1 && DRV_FROM_TM(lchip))
            {
                if (8 == p_queue->queue_id) /*mcast*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 1;
                }
                else if (9 == p_queue->queue_id)/*log*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM));
                }
                else if (10 == p_queue->queue_id)/*cpu*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM))+ 2;
                }
                else if (11 == p_queue->queue_id && p_usw_queue_master[lchip]->queue_num_per_stk_port == 1)/*c2c*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 3;
                }
            }
            else if ((p_usw_queue_master[lchip]->enq_mode == 1 && DRV_IS_DUET2(lchip))
                || p_usw_queue_master[lchip]->enq_mode == 2)
            {
                if (8 == p_queue->queue_id) /*cpu ctl queue*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 2;
                }
                else if (9 == p_queue->queue_id)/*log*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM));
                }
                else if (10 == p_queue->queue_id && p_usw_queue_master[lchip]->queue_num_per_stk_port == 1) /*c2c ctl queue*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 3;
                }
            }
            else
            {
                if (8 == p_queue->queue_id) /*cpu ctl queue*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 2;
                }
                else if (9 == p_queue->queue_id && p_usw_queue_master[lchip]->queue_num_per_stk_port == 1) /*c2c ctl queue*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 3;
                }
            }
        }
        else
        {
            SYS_QOS_QUE_BASE(queue_base, channel, p_queue->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL) + (channel * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM))));
            *queue_id  =  queue_base + p_queue->queue_id;
        }
    }

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "channel:%d, lport:%d, queue_id:%d\n", channel, lport, *queue_id);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_port_extender_get_queue(void* bucket_data, void* user_data)
{
    uint8 gchip = 0;
    sys_extend_que_node_t *p_port_extender = (sys_extend_que_node_t *)bucket_data;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_qos_queue_id_t *queue_id = (ctc_qos_queue_id_t *)traversal_data->data;
    if(p_port_extender->type != SYS_EXTEND_QUE_TYPE_SERVICE)
    {
        return CTC_E_NONE;
    }

    if(p_port_extender->group_id == traversal_data->value2)
    {
        CTC_ERROR_RETURN(sys_usw_get_gchip_id(traversal_data->value1, &gchip));
        queue_id->queue_type = CTC_QUEUE_TYPE_SERVICE_INGRESS;
        queue_id->service_id = p_port_extender->service_id;
        queue_id->gport = CTC_MAP_LPORT_TO_GPORT(gchip, p_port_extender->lport);
        queue_id->queue_id = traversal_data->value3;
    }
    return CTC_E_NONE;
}

int32
sys_usw_queue_id_get_queue(uint8 lchip, ctc_qos_queue_id_t* p_queue,uint16 queue_id)
{
    uint16  channel = 0;
    uint8  gchip = 0;
    uint16 index = 0;
    uint16 queue_offset = 0;
    uint16 queue_base = 0;
    uint16 sub_queue_id_min = 0;
    uint16 sub_queue_id_max = 0;

    if((DRV_FROM_TMM(lchip) && (queue_id < (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP) - MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM)) || queue_id > MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC)))
        || (!DRV_FROM_TMM(lchip) && (SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_NETWORK_CTL_QUEUE(queue_id) || SYS_IS_MISC_CHANNEL_QUEUE(queue_id))))
    {
        CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
        CTC_ERROR_RETURN(sys_usw_get_channel_by_queue_id(lchip, queue_id, &channel));
        p_queue->queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
        p_queue->gport = CTC_MAP_LPORT_TO_GPORT(gchip, SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, channel));
        if(queue_id >= MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC))
        {
            queue_offset = queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) - (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM));
            if(1 != p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_CPU)/*cpu ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_CPU_2;
            }
            else if(0 == p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_C2C)/*c2c ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_C2C_0;
            }
            else if(1 == p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_MC)/*mc ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_MC_1;
            }
            else if(1 == p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_SPAN)/*log ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_SPAN_1;
            }
            else if(1 == p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_CPU)/*log ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_CPU_1;
            }
            else if(1 == p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_C2C)/*c2c ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_C2C_1;
            }
            else if(2 == p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_SPAN)/*log ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_SPAN_2;
            }
            else if(2 == p_usw_queue_master[lchip]->enq_mode && queue_offset == SYS_QOS_QUEUE_HW_CTL_QUEUE_C2C)/*c2c ctl queue*/
            {
                p_queue->queue_id = SYS_QOS_QUEUE_SW_CTL_QUEUE_C2C_2;
            }
        }
        else
        {
            SYS_QOS_QUE_BASE(queue_base, channel, 0, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL) + (channel * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM))));
            p_queue->queue_id = queue_id - queue_base;
        }
    }
    else if(SYS_IS_CPU_QUEUE(queue_id))
    {
        queue_offset = queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP);
        for(index = 0; index < CTC_PKT_CPU_REASON_MAX_COUNT; index++)
        {
            sub_queue_id_min = p_usw_queue_master[lchip]->cpu_reason[index].sub_queue_id & 0xFF;
            sub_queue_id_max = (index == CTC_PKT_CPU_REASON_C2C_PKT) ? (sub_queue_id_min + MCHIP_CAP(SYS_CAP_QOS_REASON_C2C_MAX_QUEUE_NUM) - 1)
                : (CTC_IS_BIT_SET(p_usw_queue_master[lchip]->cpu_reason[index].sub_queue_id, SYS_REASON_PRI_ENQ_SHIFT) ? (sub_queue_id_min + MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM) - 1) : sub_queue_id_min);
            if(sub_queue_id_min <= queue_offset && queue_offset <= sub_queue_id_max)
            {
                p_queue->queue_type = CTC_QUEUE_TYPE_EXCP_CPU;
                p_queue->cpu_reason = index;
                p_queue->queue_id = queue_offset - sub_queue_id_min;
                break;
            }
        }
    }
    else
    {
        uint16 queue_id_base = 0;
        sys_traverse_t user_data;

        if (DRV_FROM_TMM(lchip))
        {
            user_data.data = p_queue;
            user_data.value1 = lchip;
            SYS_TMM_GROUP_ID(user_data.value2, queue_id, 1);
            SYS_TMM_QUE_ID_FR_GROUP(queue_id_base, user_data.value2, 1);
            user_data.value3 = queue_id - queue_id_base;
        }
        else
        {
            user_data.data = p_queue;
            user_data.value1 = lchip;
            user_data.value2 = (queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)) / MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
            user_data.value3 = (queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)) % MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
        }

        CTC_ERROR_RETURN(ctc_hash_traverse(p_usw_queue_master[lchip]->p_port_extender_hash,
                                           _sys_usw_queue_port_extender_get_queue, (void *)&user_data));
    }

    return CTC_E_NONE;
}

/*check_type:0 for exactly, 1 for fuzzy*/
int32
_sys_usw_queue_get_service_queue_id(uint8 lchip, uint8 check_type, ctc_qos_queue_id_t* p_queue, uint16* queue_id)
{
    uint16 lport = 0;
    uint16 group_id = 0;
    uint16 queue_base = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node = NULL;
    sys_extend_que_node_t* p_service_que_node1 = NULL;
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    
    if(DRV_FROM_AT(lchip))
    {
        return CTC_E_INVALID_PARAM;
    }
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_queue->gport, lchip, lport);
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = p_queue->service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if(p_usw_queue_master[lchip]->service_queue_mode == 1 && p_service_que_node!=NULL && (p_service_que_node->group_is_alloc & 0x80))
    {
        if((check_type && p_service_que_node->queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) != p_queue->queue_id) 
            || (!check_type && p_service_que_node->queue_id != p_queue->queue_id))
        {
            return CTC_E_INVALID_PARAM;
        }
        group_id = p_service_que_node->group_id;
        p_queue->queue_id = p_queue->queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
    }
    else
    {
        service_que_node.dir = CTC_EGRESS;
        p_service_que_node1 = sys_usw_port_extender_lookup(lchip, &service_que_node);
        if (NULL == p_service_que_node && (NULL == p_service_que_node1 || p_service_que_node1->group_is_alloc == 0))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        else if(NULL != p_service_que_node1 && NULL != p_service_que_node)
        {
            return CTC_E_INVALID_PARAM;
        }
        else if(NULL == p_service_que_node && NULL != p_service_que_node1 && (p_service_que_node1->group_is_alloc & 0x80))
        {
            if((check_type && p_service_que_node1->queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) != p_queue->queue_id) 
                || (!check_type && p_service_que_node1->queue_id != p_queue->queue_id))
            {
                return CTC_E_INVALID_PARAM;
            }
            group_id = p_service_que_node1->group_id;
            p_queue->queue_id = p_queue->queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
        }
        else
        {
            group_id = (p_service_que_node == NULL) ? p_service_que_node1->group_id : p_service_que_node->group_id;
            CTC_MAX_VALUE_CHECK(p_queue->queue_id, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) - 1);
        }
    }
    
    
    if (DRV_FROM_TMM(lchip))
    {
        if (group_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_GRP_BASE_16Q))
        {
            queue_base = group_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP);
        }
        else
        {
            queue_base = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_16Q) + (group_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_GRP_BASE_16Q)) * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP_16Q);
        }
    }
    else
    {
        queue_base = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) + group_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
    }

    *queue_id = queue_base + p_queue->queue_id;
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "queue_id:%d\n", *queue_id);
    return CTC_E_NONE;
}

/*
 get queue id by queue type
*/
int32
sys_usw_queue_get_queue_id(uint8 lchip, ctc_qos_queue_id_t* p_queue, uint16* queue_id)
{
    uint16 channel = 0;
    uint16 lport = 0;
    uint32 dot1ae_en = 0;
    uint8 stacking_queue_en = 0;
    uint8 bpe_en = 0;
    uint16 group_id = 0;
    uint8 ext_que_en = 0;
    uint16 queue_base = 0;
    sys_extend_que_node_t port_extender_node;
    sys_extend_que_node_t* p_port_extender_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&port_extender_node, 0, sizeof(port_extender_node));

    switch (p_queue->queue_type)
    {
    case CTC_QUEUE_TYPE_NETWORK_EGRESS:
    case CTC_QUEUE_TYPE_INTERNAL_PORT:
    {
        CTC_ERROR_RETURN(_sys_usw_get_channel_by_port(lchip, p_queue->gport, &channel));
        _sys_usw_queue_get_ext_queue_enable(lchip, p_queue->gport, &stacking_queue_en, &bpe_en, &dot1ae_en, &ext_que_en);

        if (ext_que_en)/*add port to trunk or bpe*/
        {
            CTC_ERROR_RETURN(_sys_usw_queue_get_ext_queue_id(lchip, p_queue, queue_id));
        }
        else if (0 == p_usw_queue_master[lchip]->enq_mode
            || 2 == p_usw_queue_master[lchip]->enq_mode) /* 8(uc+mc)*/
        {
            CTC_MAX_VALUE_CHECK(p_queue->queue_id, p_usw_queue_master[lchip]->queue_num_per_chanel - 1);
            if (8 == p_queue->queue_id) /*cpu ctl queue*/
            {
                *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 2;
            }
            else if (9 == p_queue->queue_id) /*log ctl queue*/
            {
                *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM));
            }
            else if (10 == p_queue->queue_id && p_usw_queue_master[lchip]->queue_num_per_stk_port == 1) /*c2c ctl queue*/
            {
                *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 3;
            }
            else
            {
                SYS_QOS_QUE_BASE(queue_base, channel, p_queue->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL) + (channel * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM))));
                *queue_id  =  queue_base + p_queue->queue_id;
            }
        }
        else if(1 == p_usw_queue_master[lchip]->enq_mode || 2 == p_usw_queue_master[lchip]->enq_mode)/*ctl queue or d2 macast queue*/
        {
            CTC_MAX_VALUE_CHECK(p_queue->queue_id, p_usw_queue_master[lchip]->queue_num_per_chanel - 1);
            if(p_usw_queue_master[lchip]->enq_mode == 1 && DRV_FROM_TM(lchip))
            {
                if (8 == p_queue->queue_id) /*mcast*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 1;
                }
                else if (9 == p_queue->queue_id)/*log*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM));
                }
                else if (10 == p_queue->queue_id)/*cpu*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 2;
                }
                else if (11 == p_queue->queue_id && p_usw_queue_master[lchip]->queue_num_per_stk_port == 1)/*c2c*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM)) + 3;
                }
                else
                {
                    SYS_QOS_QUE_BASE(queue_base, channel, p_queue->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL) + (channel * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM))));
                    *queue_id  =  queue_base + p_queue->queue_id;
                }
            }
            else if(p_usw_queue_master[lchip]->enq_mode == 1 && DRV_IS_DUET2(lchip) )
            {
                if((MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN)+MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)) == p_queue->queue_id)/*log*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM));
                }
                else if((MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN)+MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) + 1) == p_queue->queue_id)/*cpu*/
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) + (channel * MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM) + 2);
                }
                else if(p_queue->queue_id < (MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN)+MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP))
                        && p_queue->queue_id > (MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN)-1))
                {
                    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_queue->gport, lchip, lport);
                    port_extender_node.type = SYS_EXTEND_QUE_TYPE_MCAST;
                    port_extender_node.lchip = lchip;
                    port_extender_node.lport = lport;
                    p_port_extender_node = sys_usw_port_extender_lookup(lchip, &port_extender_node);
                    if (NULL == p_port_extender_node)
                    {
                        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                        return CTC_E_NOT_EXIST;
                    }
                    group_id = p_port_extender_node->group_id;
                    *queue_id = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)+ (group_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP))
                                + p_queue->queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP);
                }
                else
                {
                    *queue_id  =  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL) + (channel * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM)) + p_queue->queue_id;
                }
            }
        }

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "channel:%d, queue_id:%d\n", channel, *queue_id);
    }
    break;
    case CTC_QUEUE_TYPE_EXCP_CPU:
    {
        sys_cpu_reason_t  *p_cpu_reason;

        if(SYS_MAP_CTC_GPORT_TO_PORT_TYPE(p_queue->gport) == CTC_GPORT_TYPE_DMA)
        {
            CTC_MAX_VALUE_CHECK(p_queue->queue_id, MCHIP_CAP(SYS_CAP_REASON_TOTAL_QUEUE_NUM));
            *queue_id = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP) + p_queue->queue_id;
            return CTC_E_NONE;
        }

        if (p_queue->cpu_reason >= CTC_PKT_CPU_REASON_MAX_COUNT)
        {
            return CTC_E_INVALID_PARAM;
        }

        p_cpu_reason = &p_usw_queue_master[lchip]->cpu_reason[p_queue->cpu_reason];
        if ((p_cpu_reason->sub_queue_id&0xFF) == 0xFF)
        {
            return CTC_E_NOT_READY;
        }
        if (p_queue->cpu_reason == CTC_PKT_CPU_REASON_C2C_PKT)
        {
            CTC_MAX_VALUE_CHECK(p_queue->queue_id, MCHIP_CAP(SYS_CAP_QOS_REASON_C2C_MAX_QUEUE_NUM) - 1);
        }
        else if(CTC_IS_BIT_SET(p_cpu_reason->sub_queue_id, SYS_REASON_PRI_ENQ_SHIFT))
        {
            CTC_MAX_VALUE_CHECK(p_queue->queue_id, MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM) - 1);
        }
        else
        {
            CTC_MAX_VALUE_CHECK(p_queue->queue_id, 0);
        }

        if (p_cpu_reason->dest_type == CTC_PKT_CPU_REASON_TO_LOCAL_CPU)
        {
            *queue_id = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP) + (p_cpu_reason->sub_queue_id&0xFF) + p_queue->queue_id;
        }
        else if (p_cpu_reason->dest_type == CTC_PKT_CPU_REASON_TO_LOCAL_CPU_ETH)
        {
            uint16 cpu_eth_chan_id = p_usw_queue_master[lchip]->cpu_eth_chan_id;
            if (DRV_FROM_TMM(lchip))
            {
                  uint16 cpu_channel[SYS_USW_CPU_MAC_NUM] = {MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC1),
                                                          MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC2), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC3)};

                  cpu_eth_chan_id = cpu_channel[p_cpu_reason->dest_port&0x3];
            }
            SYS_QOS_QUE_BASE(queue_base, cpu_eth_chan_id, p_queue->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL)
                + cpu_eth_chan_id * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM)));

            *queue_id = queue_base + p_queue->queue_id;
        }
        else
        {
            /*TBD*/
            return CTC_E_INVALID_PARAM;
        }
    }
    break;
    case CTC_QUEUE_TYPE_ILOOP:
        CTC_MAX_VALUE_CHECK(p_queue->queue_id, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN) - 1);

        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_CHANID_ILOOP), p_queue->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL)
                         + (MCHIP_CAP(SYS_CAP_CHANID_ILOOP) * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM))));
        *queue_id = queue_base + p_queue->queue_id;
        break;

    case CTC_QUEUE_TYPE_ELOOP:

        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_CHANID_ELOOP), p_queue->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL)
                         + (MCHIP_CAP(SYS_CAP_CHANID_ELOOP) * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM))));
        *queue_id = queue_base + p_queue->queue_id;
        break;
    case CTC_QUEUE_TYPE_OAM:
        CTC_MAX_VALUE_CHECK(p_queue->queue_id, MCHIP_CAP(SYS_CAP_QOS_OAM_QUEUE_NUM) - 1);

        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_CHANID_OAM), p_queue->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL)
                         + (MCHIP_CAP(SYS_CAP_CHANID_OAM) * MCHIP_CAP(SYS_CAP_QOS_NORMAL_QUEUE_NUM))));
        *queue_id = queue_base + p_queue->queue_id;
        break;
    case CTC_QUEUE_TYPE_SERVICE_INGRESS:
        {
            CTC_ERROR_RETURN(_sys_usw_queue_get_service_queue_id(lchip, 0, p_queue, queue_id));
        }
        break;
    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

uint8
_sys_usw_queue_get_enq_mode(uint8 lchip)
{
    return p_usw_queue_master[lchip]->enq_mode;
}

uint8
_sys_usw_queue_get_service_queue_mode(uint8 lchip)
{
    return p_usw_queue_master[lchip]->service_queue_mode;
}

int32
sys_usw_queue_get_queue_type_by_queue_id(uint8 lchip, uint16 queue_id, uint8 *queue_type)
{
    CTC_PTR_VALID_CHECK(queue_type);

    if (SYS_IS_CPU_QUEUE(queue_id))
    {
        *queue_type = SYS_QUEUE_TYPE_EXCP;
    }
    else if (SYS_IS_EXT_QUEUE(queue_id))
    {
        *queue_type = SYS_QUEUE_TYPE_EXTEND;
    }
    else
    {
        *queue_type = SYS_QUEUE_TYPE_NORMAL;
    }

    return CTC_E_NONE;
}

int32
sys_usw_get_channel_by_queue_id(uint8 lchip, uint16 queue_id, uint16 *channel)
{
    uint32 field_val = 0;
    uint32 cmd = 0;
    uint16 group_id = 0;

    if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_get_chan_by_que_id)
    {
        return MCHIP_QOS(lchip)->qos_queue_get_chan_by_que_id(lchip, queue_id, channel);
    }

    if (SYS_IS_NETWORK_BASE_QUEUE(queue_id))
    {
        *channel = queue_id / 8;
    }
    else if (SYS_IS_MISC_CHANNEL_QUEUE(queue_id))
    {
        *channel = queue_id / 8;
    }
    else if (SYS_IS_CPU_QUEUE(queue_id))
    {
        if (p_usw_queue_master[lchip]->max_dma_rx_num == 4)
        {
            *channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0) + (queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP)) / 32;
        }
        else
        {
            *channel = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0) + (queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP)) / 64;
        }
    }
    else if (SYS_IS_NETWORK_CTL_QUEUE(queue_id))
    {
        *channel = (queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC)) / MCHIP_CAP(SYS_CAP_QOS_MISC_QUEUE_NUM) ;
    }
    else if (SYS_IS_EXT_QUEUE(queue_id))
    {
        group_id = (queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)) / MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
        cmd = DRV_IOR(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
        *channel = field_val;
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_get_channel_by_port(uint8 lchip, uint32 gport, uint16 *channel)
{
    uint16 lport = 0;
    uint32 field_val = 0;
    uint32 chan_id = 0;
    uint32 cmd = 0;
    uint8 pmac_channel[24] = {4,5,6,7,16,17,18,19,8,9,10,11,24,25,26,27,40,41,42,43,56,57,58,59};
    uint8 index = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    if (DRV_FROM_TMM(lchip) && (((gport >> CTC_TYPE_PORT_OFFSET) & CTC_TYPE_PORT_MASK) == CTC_GPORT_TYPE_CPU_MAC))
    {
        uint8  is_network = 0;
        uint8  cpu_mac_id = SYS_MAP_CTC_GPORT_TO_DRV_LPORT(gport)&0x3;
        uint8  cpu_mac_channel[SYS_USW_CPU_MAC_NUM] = {MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC1),
                                                        MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC2), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC3)};

        if (MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx)
        {
             CTC_ERROR_RETURN(MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx(lchip,cpu_mac_id,&lport,&is_network));
             if(!is_network)
             {
                 *channel = cpu_mac_channel[cpu_mac_id];
                 return CTC_E_NONE;
             }
        }
    }

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);

    if(!DRV_IS_DUET2(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_port_get_property(lchip, gport, CTC_PORT_PROP_XPIPE_EN, &field_val));
        if(field_val && DRV_IS_TSINGMA(lchip))
        {
            for(index = 0; index < 24; index ++)
            {
                if(pmac_channel[index] == lport)
                {
                    *channel = lport;
                    return CTC_E_NONE;
                }
            }
        }
        /* TM.MX pmac channel and emac channel has swaped, so TM.MX get emac channel */
        if (field_val && DRV_FROM_TMM(lchip))
        {
            dmps_port_info.gport = gport;
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
            *channel = chan_id;
            return CTC_E_NONE;
        }
    }
    cmd = DRV_IOR(DsQWriteDestPortChannelMap_t, DsQWriteDestPortChannelMap_channelId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, lport, cmd, &field_val));
    *channel = SYS_USW_CHANNEL_DECODE(field_val); /* for TMG, convert 0-255 to 0-127 */

    return CTC_E_NONE;
}

int32
_sys_usw_add_port_to_channel(uint8 lchip, uint32 lport, uint16 channel, uint8 is_pp)
{
    ds_t ds;
    uint32 cmd = 0;
    uint32 field_val = SYS_USW_CHANNEL_ENCODE(channel);

    sal_memset(ds, 0, sizeof(ds));
    cmd = DRV_IOR(DsQWriteDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    SetDsQWriteDestPortChannelMap(V, channelId_f, ds, field_val);
    cmd = DRV_IOW(DsQWriteDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    cmd = DRV_IOR(DsDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    SetDsDestPortChannelMap(V, channelId_f, ds, field_val);
    cmd = DRV_IOW(DsDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    cmd = DRV_IOW(DsLinkAggregationPortChannelMap_t, DsLinkAggregationPortChannelMap_channelId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, lport, cmd, &field_val));

    return CTC_E_NONE;
}

int32
_sys_usw_remove_port_from_channel(uint8 lchip, uint32 lport)
{
    ds_t   ds;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint8 gchip = 0;
    uint32 channel = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    dmps_port_info.gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel));

    /* for TMG, chan bit7 is dpid, bit6 is not use */
    field_val = !SYS_IS_NETWORK_CHANNEL(channel) ? MCHIP_CAP(SYS_CAP_CHANID_DROP) : SYS_USW_CHANNEL_ENCODE(channel);

    sal_memset(ds, 0, sizeof(ds));
    cmd = DRV_IOR(DsQWriteDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    SetDsQWriteDestPortChannelMap(V, channelId_f, ds, field_val);
    cmd = DRV_IOW(DsQWriteDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    cmd = DRV_IOR(DsDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    SetDsQWriteDestPortChannelMap(V, channelId_f, ds, field_val);
    cmd = DRV_IOW(DsDestPortChannelMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, lport, cmd, ds));

    cmd = DRV_IOW(DsLinkAggregationPortChannelMap_t, DsLinkAggregationPortChannelMap_channelId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, lport, cmd, &field_val));

    return CTC_E_NONE;
}

/**
 @brief set priority color map to queue select and drop_precedence.
*/
int32
sys_usw_set_priority_queue_map(uint8 lchip, ctc_qos_pri_map_t* p_queue_pri_map)
{
    uint32 index = 0;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint8 mcast = 0;
    uint8 dpid = 0;
    DsErmPrioScTcMap_m erm_prio_sc_tc_map;
    DsErmColorDpMap_m erm_color_dp_map;
    MetFifoPriorityMap_m met_fifo_prio_map;

    CTC_MAX_VALUE_CHECK(p_queue_pri_map->priority, SYS_QOS_QUEUE_ENQ_PRIORITY_MAX);
    CTC_VALUE_RANGE_CHECK(p_queue_pri_map->color, SYS_QOS_QUEUE_ENQ_COLOR_MIN, SYS_QOS_QUEUE_ENQ_COLOR_MAX);
    CTC_MAX_VALUE_CHECK(p_queue_pri_map->queue_select, SYS_QOS_QUEUE_ENQ_QUEUE_SELECT_MAX);
    CTC_MAX_VALUE_CHECK(p_queue_pri_map->drop_precedence, SYS_QOS_QUEUE_ENQ_ROP_PRECEDENCE_MAX);
    CTC_MAX_VALUE_CHECK(p_queue_pri_map->rep_queue_select, SYS_QOS_QUEUE_ENQ_REP_QUEUE_SELECT_MAX);

    /* now we only use profile0 */
    for (mcast = 0; mcast < 2; mcast++)
    {
        index = mcast << 4 | p_queue_pri_map->priority;
        field_val = p_queue_pri_map->queue_select;
        sal_memset(&erm_prio_sc_tc_map, 0, sizeof(DsErmPrioScTcMap_m));
        cmd = DRV_IOR(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
        SetDsErmPrioScTcMap(V, g2_0_mappedTc_f, &erm_prio_sc_tc_map, field_val);
        SetDsErmPrioScTcMap(V, g2_1_mappedTc_f, &erm_prio_sc_tc_map, field_val);
        SetDsErmPrioScTcMap(V, g2_2_mappedTc_f, &erm_prio_sc_tc_map, field_val);
        SetDsErmPrioScTcMap(V, g2_3_mappedTc_f, &erm_prio_sc_tc_map, (DRV_FROM_TMM(lchip) || field_val < 6) ? field_val : 6);
        SetDsErmPrioScTcMap(V, g2_4_mappedTc_f, &erm_prio_sc_tc_map, field_val);
        /*SetDsErmPrioScTcMap(V, g2_5_mappedTc_f, &erm_prio_sc_tc_map, field_val); *//*SYS_ERM_PROFILE_ETS*/
        SetDsErmPrioScTcMap(V, g2_6_mappedTc_f, &erm_prio_sc_tc_map, (!DRV_FROM_TMM(lchip) || field_val < 6) ? field_val : 6);
        SetDsErmPrioScTcMap(V, g2_7_mappedTc_f, &erm_prio_sc_tc_map, field_val);
        cmd = DRV_IOW(DsErmPrioScTcMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_prio_sc_tc_map));
    }

    /* update uc and mc color map tp dropPrecedence */
    sal_memset(&erm_color_dp_map, 0, sizeof(DsErmColorDpMap_m));
    for (mcast = 0; mcast < 2; mcast++)
    {
        index = mcast << 2 | p_queue_pri_map->color;
        cmd = DRV_IOR(DsErmColorDpMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_color_dp_map));
        SetDsErmColorDpMap(V, g_0_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);
        SetDsErmColorDpMap(V, g_1_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);
        SetDsErmColorDpMap(V, g_2_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);
        SetDsErmColorDpMap(V, g_3_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);
        SetDsErmColorDpMap(V, g_4_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);
        /*SetDsErmColorDpMap(V, g_5_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);*//*SYS_ERM_PROFILE_ETS*/
        SetDsErmColorDpMap(V, g_6_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);
        SetDsErmColorDpMap(V, g_7_dropPrecedence_f, &erm_color_dp_map, p_queue_pri_map->drop_precedence);    
        cmd = DRV_IOW(DsErmColorDpMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_color_dp_map));
    }

    sal_memset(&met_fifo_prio_map, 0, sizeof(MetFifoPriorityMap_m));
    index = p_queue_pri_map->priority;
    cmd = DRV_IOR(MetFifoPriorityMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &met_fifo_prio_map));
    if (p_queue_pri_map->color == CTC_QOS_COLOR_GREEN)
    {
        SetMetFifoPriorityMap(V, metFifoHighPriorityG_f, &met_fifo_prio_map, p_queue_pri_map->rep_queue_select); 
    }
    else if (p_queue_pri_map->color == CTC_QOS_COLOR_YELLOW)
    {
        SetMetFifoPriorityMap(V, metFifoHighPriorityY_f, &met_fifo_prio_map, p_queue_pri_map->rep_queue_select); 
    }
    else if (p_queue_pri_map->color == CTC_QOS_COLOR_RED)
    {
        SetMetFifoPriorityMap(V, metFifoHighPriorityR_f, &met_fifo_prio_map, p_queue_pri_map->rep_queue_select); 
    }
    cmd = DRV_IOW(MetFifoPriorityMap_t, DRV_ENTRY_FLAG);
    for (dpid = 0; dpid < MCHIP_CAP(SYS_CAP_DP_MAX_NUM); dpid++)
    {
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, dpid << 4 | index, cmd, &met_fifo_prio_map));
    }
    return CTC_E_NONE;
}


/**
 @brief set priority color map to queue select and drop_precedence.
*/
int32
sys_usw_get_priority_queue_map(uint8 lchip, ctc_qos_pri_map_t* p_queue_pri_map)
{
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 field_id[MAX_CTC_QOS_COLOR - 1] = {MetFifoPriorityMap_metFifoHighPriorityR_f, 
                                              MetFifoPriorityMap_metFifoHighPriorityY_f, 
                                              MetFifoPriorityMap_metFifoHighPriorityG_f};

    CTC_MAX_VALUE_CHECK(p_queue_pri_map->priority, SYS_QOS_QUEUE_ENQ_PRIORITY_MAX);
    CTC_VALUE_RANGE_CHECK(p_queue_pri_map->color, SYS_QOS_QUEUE_ENQ_COLOR_MIN, SYS_QOS_QUEUE_ENQ_COLOR_MAX);

    /* now we only use profile0 */
    cmd = DRV_IOR(DsErmPrioScTcMap_t, DsErmPrioScTcMap_g2_0_mappedTc_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_queue_pri_map->priority, cmd, &value));
    p_queue_pri_map->queue_select = value;

    cmd = DRV_IOR(DsErmColorDpMap_t, DsErmColorDpMap_g_0_dropPrecedence_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_queue_pri_map->color, cmd, &value));
    p_queue_pri_map->drop_precedence = value;

    cmd = DRV_IOR(MetFifoPriorityMap_t, field_id[p_queue_pri_map->color - 1]); 
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_queue_pri_map->priority, cmd, &value));
    p_queue_pri_map->rep_queue_select = value;

    return CTC_E_NONE;
}

int32
_sys_usw_set_dma_channel_drop_en(uint8 lchip, bool enable)
{
    uint32 cmd = 0;
    uint8 channel_min = 0;
    uint8 channel_max = 0;
    QWriteRsvChanCtl_m qmgr_rsv_channel_range;

    sal_memset(&qmgr_rsv_channel_range, 0, sizeof(qmgr_rsv_channel_range));

    if (DRV_IS_TMG(lchip))
    {
        channel_min = enable ? SYS_USW_CHANNEL_ENCODE(MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0)) : SYS_USW_CHANNEL_ENCODE(MCHIP_CAP(SYS_CAP_CHANID_RSV) + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM));
        channel_max = enable ? SYS_USW_CHANNEL_ENCODE(MCHIP_CAP(SYS_CAP_CHANID_DMA_RX1)): SYS_USW_CHANNEL_ENCODE(MCHIP_CAP(SYS_CAP_CHANID_RSV) + MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM));
    }
    else
    {
        channel_min = enable ? MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0) : MCHIP_CAP(SYS_CAP_CHANID_RSV);
        channel_max = enable ? (DRV_FROM_TMM(lchip)?MCHIP_CAP(SYS_CAP_CHANID_DMA_RX1): MCHIP_CAP(SYS_CAP_CHANID_DMA_RX3)): MCHIP_CAP(SYS_CAP_CHANID_RSV);
    }

    cmd = DRV_IOR(QWriteRsvChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmgr_rsv_channel_range));

    SetQWriteRsvChanCtl(V, g_1_reservedChannelRangeValid_f, &qmgr_rsv_channel_range, 1);
    SetQWriteRsvChanCtl(V, g_1_reservedChannelRangeMax_f, &qmgr_rsv_channel_range, channel_max);
    SetQWriteRsvChanCtl(V, g_1_reservedChannelRangeMin_f, &qmgr_rsv_channel_range, channel_min);
    cmd = DRV_IOW(QWriteRsvChanCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmgr_rsv_channel_range));
    return CTC_E_NONE;
}

int32
_sys_usw_qos_set_aqmscan_high_priority_en(uint8 lchip, bool enable)
{
    uint32 cmd = 0;
    uint32 value = 0;

    value = (enable == 1) ? 0 : 1;
    cmd = DRV_IOW(QMgrEnqMiscCtl_t, QMgrEnqMiscCtl_cfgAqmScanLowPrioEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

    return CTC_E_NONE;
}

int32
sys_usw_queue_set_stats_enable(uint8 lchip, ctc_qos_queue_stats_t* p_stats)
{
    uint32 cmd = 0;
    uint32 value = 0;
    uint16 queue_id = 0;
    sys_stats_param_t sts_param;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&sts_param, 0, sizeof(sts_param));
    sts_param.type = SYS_STATS_TYPE_QUEUE;
    sts_param.num = 2;

    value = (p_stats->stats_en) ? 1 : 0;
    if(DRV_IS_DUET2(lchip))
    {
        cmd = DRV_IOW(QWriteCtl_t, QWriteCtl_queStatsEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

        cmd = DRV_IOW(GlobalStatsUpdateEnCtl_t, GlobalStatsUpdateEnCtl_qMgrGlobalStatsUpdateEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    }
    else if(DRV_IS_TSINGMA(lchip))
    {
        CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &p_stats->queue, &queue_id));
        if (!SYS_IS_EXT_QUEUE(queue_id))
        {
            cmd = DRV_IOW(QWriteCtl_t, QWriteCtl_queStatsEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

            cmd = DRV_IOW(GlobalStatsUpdateEnCtl_t, GlobalStatsUpdateEnCtl_qMgrGlobalStatsUpdateEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
            return CTC_E_NONE;
        }
        cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &sts_param.ptr));
        if(value == 1 && sts_param.ptr == 0)
        {
            CTC_ERROR_RETURN(sys_usw_flow_stats_alloc_statsptr(lchip, &sts_param));
            cmd = DRV_IOW(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &sts_param.ptr));
            value = 0;
            cmd = DRV_IOW(DsErmQueueCfg_t, DsErmQueueCfg_statsMode_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &value));
        }
        else if(value == 0 && sts_param.ptr != 0)
        {
            CTC_ERROR_RETURN(sys_usw_flow_stats_free_statsptr(lchip, &sts_param));
            value = 0;
            cmd = DRV_IOW(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &value));
        }
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_get_stats_enable(uint8 lchip, uint16 queue_id, uint8* p_enable)
{
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 value1 = 0;
    if (DRV_IS_TSINGMA(lchip))
    {
        cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &value));
        cmd = DRV_IOR(QWriteCtl_t, QWriteCtl_queStatsEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value1));
        *p_enable = (value && value1) ? 1 : 0;
    }
    else if(DRV_IS_DUET2(lchip))
    {
        cmd = DRV_IOR(QWriteCtl_t, QWriteCtl_queStatsEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        *p_enable = value;
    }
    else if(DRV_FROM_TMM(lchip))
    {
        *p_enable = 1;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_alloc_ext_queueid(uint8 lchip, uint32 service_id, uint32 dest_port,uint32 chan_id, uint8 dir,
                                                uint16 queue_id,  uint32* group_id)
{
    int32  ret = 0;
    uint32 cmd = 0;
    uint32 loop = 0;
    uint16 loop_end = 0;
    uint16 lport = 0;
    uint8  flag = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t *p_tmp_service_node = NULL;
    sys_queue_group_node_t *p_sys_group_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_MAX_VALUE_CHECK(queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) - MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) - 1));

    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dest_port, lchip, lport);
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    service_que_node.dir = dir;
    /*service_queue_mode != 1, service_id max value is all 16bit set*/
    loop_end = p_usw_queue_master[lchip]->service_queue_mode == 1 ? MCHIP_CAP(SYS_CAP_SERVICE_ID_NUM) : 0xffff;
    for(loop = 1; loop < loop_end; loop ++)
    {
        service_que_node.service_id = loop;
        p_tmp_service_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
        if(p_tmp_service_node == NULL)
        {
            continue;
        }
        if(p_tmp_service_node->group_is_alloc && (queue_id /MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) == p_tmp_service_node->queue_id/MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP))
           && (ABS(queue_id-p_tmp_service_node->queue_id)<MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)))
        {
            *group_id = p_tmp_service_node->group_id;
            break;
        }
    }
    if(loop == loop_end || (p_tmp_service_node && p_tmp_service_node->group_is_alloc == 0))
    {
        flag = 1;
        ret = _sys_usw_queue_alloc_ext_group(lchip, 1, 1, group_id);
        if (ret < 0)
        {
            return ret;
        }
        cmd = DRV_IOW(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, *group_id, cmd, &chan_id), ret, error0);
        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, *group_id);
        if (NULL == p_sys_group_node)
        {
             SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
             ret = CTC_E_NOT_EXIST;
             goto error0;
        }
        p_sys_group_node->chan_id  = chan_id;  /*0~63*/
    }

    return CTC_E_NONE;

error0:
    if(flag)
    {
        _sys_usw_queue_free_ext_group(lchip, 1, *group_id);
    }
    return ret;
}

int32
_sys_usw_queue_free_ext_queueid(uint8 lchip, uint32 service_id, uint32 dest_port, uint8 dir)
{
    uint32 cmd = 0;
    uint16 lport = 0;
    uint32 loop = 0;
    uint16 loop_end = 0;
    uint8 flag = 1;
    DsQMgrGrpChanMap_m    grp_chan_map;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node ,*p_tmp_service_node;
    sys_queue_group_node_t *p_sys_group_node = NULL;

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dest_port, lchip, lport);
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    service_que_node.dir = dir;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if(p_service_que_node == NULL)
    {
        return CTC_E_NOT_EXIST;
    }
    /*service_queue_mode != 1, service_id max value is all 16bit set*/
    loop_end = p_usw_queue_master[lchip]->service_queue_mode == 1 ? MCHIP_CAP(SYS_CAP_SERVICE_ID_NUM) : 0xffff;
    for(loop = 1; loop < loop_end; loop ++)
    {
        service_que_node.service_id = loop;
        p_tmp_service_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
        if(p_tmp_service_node == NULL)
        {
            continue;
        }
        if(p_tmp_service_node->service_id != service_id && p_tmp_service_node->group_is_alloc && p_tmp_service_node->group_id == p_service_que_node->group_id)
        {
            flag = 0;
            break;
        }
    }
    if(flag)
    {
        sal_memset(&grp_chan_map, 0,sizeof(grp_chan_map));
        _sys_usw_queue_free_ext_group(lchip, 1, p_service_que_node->group_id);
        cmd = DRV_IOR(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_service_que_node->group_id, cmd, &grp_chan_map));
        SetDsQMgrGrpChanMap(V, channelId_f, &grp_chan_map, 0);
        cmd = DRV_IOW(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_service_que_node->group_id, cmd, &grp_chan_map));
        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, p_service_que_node->group_id);
        if (NULL == p_sys_group_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        p_sys_group_node->chan_id  = 0xFF;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_alloc_ext_group(uint8 lchip, uint32 num, uint8 multi, uint32* group_id)
{
    uint32 grp_id = 0;
    sys_usw_opf_t opf;

    /*alloc group id*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = 0;
    opf.pool_type  = p_usw_queue_master[lchip]->opf_type_group_id;
    opf.multiple   = multi;
    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, num, &grp_id));

    *group_id = grp_id;

    return CTC_E_NONE;
}

int32
_sys_usw_queue_alloc_ext_group_from_position(uint8 lchip, uint32 num, uint32 group_id)
{
    sys_usw_opf_t opf;

    /*alloc group id*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = 0;
    opf.pool_type  = p_usw_queue_master[lchip]->opf_type_group_id;
    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset_from_position(lchip, &opf, num, group_id));

    return CTC_E_NONE;
}


int32
_sys_usw_queue_free_ext_group(uint8 lchip, uint32 num, uint32 group_id)
{
    sys_usw_opf_t opf;

    /*free group id*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = 0;
    opf.pool_type  = p_usw_queue_master[lchip]->opf_type_group_id;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, num, group_id));

    return CTC_E_NONE;
}

int32
_sys_usw_queue_alloc_key_index(uint8 lchip, uint32 num, uint32* key_index)
{
    uint32 index = 0;
    sys_usw_opf_t opf;

    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    /*alloc key index*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = 0;
    opf.pool_type  = p_usw_queue_master[lchip]->opf_type_tcam_index;
    CTC_ERROR_RETURN(sys_usw_opf_alloc_offset(lchip, &opf, num, &index));

    *key_index = index;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "alloc DsQueueMapTcamKey index is %d\n", index);
    return CTC_E_NONE;
}

int32
_sys_usw_queue_free_key_index(uint8 lchip, uint32 num, uint32 key_index)
{
    sys_usw_opf_t opf;

    /*free key index*/
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_index = 0;
    opf.pool_type  = p_usw_queue_master[lchip]->opf_type_tcam_index;
    CTC_ERROR_RETURN(sys_usw_opf_free_offset(lchip, &opf, num, key_index));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "free DsQueueMapTcamKey index is %d\n", key_index);
    return CTC_E_NONE;
}

int32
_sys_usw_queue_add_for_stacking(uint8 lchip, uint32 chan_id)
{
    int32  ret = 0;
    uint32 group_id = 0;
    uint32 key_index = 0;
    uint32 cmd = 0;
    uint32 field_val = 0;
    sys_extend_que_node_t c2c_que_node;
    sys_extend_que_node_t* p_c2c_que_node = NULL;
    sys_queue_group_node_t *p_sys_group_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NONE;
    }
    sal_memset(&c2c_que_node, 0, sizeof(sys_extend_que_node_t));

    c2c_que_node.type = SYS_EXTEND_QUE_TYPE_C2C;
    c2c_que_node.lchip = lchip;
    c2c_que_node.channel = chan_id;
    p_c2c_que_node = sys_usw_port_extender_lookup(lchip, &c2c_que_node);
    if (NULL != p_c2c_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry already exist \n");
        return CTC_E_EXIST;
    }

    p_c2c_que_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
    if (NULL == p_c2c_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }

    sal_memset(p_c2c_que_node, 0, sizeof(sys_extend_que_node_t));

    if(p_usw_queue_master[lchip]->queue_num_per_stk_port == 0)
    {
        ret = _sys_usw_queue_alloc_ext_group(lchip, 1, 1, &group_id);
        if (ret < 0)
        {
            mem_free(p_c2c_que_node);
            return ret;
        }
    }
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
    if(!DRV_FROM_TMM(lchip))
    {
        DsQueueMapTcamData_m  QueueMapTcamData;
        DsQueueMapTcamKey_m   QueueMapTcamKey;
        DsQueueMapTcamKey_m   QueueMapTcamMask;
        DsQMgrGrpChanMap_m    grp_chan_map;
        tbl_entry_t           tcam_key;

        sal_memset(&QueueMapTcamData, 0, sizeof(DsQueueMapTcamData_m));
        sal_memset(&QueueMapTcamKey, 0, sizeof(DsQueueMapTcamKey_m));
        sal_memset(&QueueMapTcamMask, 0, sizeof(DsQueueMapTcamKey_m));
        sal_memset(&grp_chan_map, 0, sizeof(DsQMgrGrpChanMap_m));

        CTC_ERROR_GOTO(_sys_usw_queue_alloc_key_index(lchip, 1, &key_index), ret, error0);
        /*write tcam ad*/
        SetDsQueueMapTcamData(V, extGroupId_f, &QueueMapTcamData, group_id );
        cmd = DRV_IOW(DsQueueMapTcamData_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index , cmd, &QueueMapTcamData), ret, error1);

        /*bind extGroup to channel*/
        SetDsQMgrGrpChanMap(V, channelId_f, &grp_chan_map, chan_id);
        cmd = DRV_IOW(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, group_id , cmd, &grp_chan_map), ret, error1);

        SetDsQueueMapTcamKey(V, c2cPacket_f, &QueueMapTcamKey, 1);
        SetDsQueueMapTcamKey(V, c2cPacket_f, &QueueMapTcamMask, 1);
        SetDsQueueMapTcamKey(V, channelId_f, &QueueMapTcamKey, chan_id);
        SetDsQueueMapTcamKey(V, channelId_f, &QueueMapTcamMask, 0x3f);
        cmd = DRV_IOW(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        tcam_key.data_entry = (uint32*)(&QueueMapTcamKey);
        tcam_key.mask_entry = (uint32*)(&QueueMapTcamMask);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index, cmd, &tcam_key), ret, error1);
    }
    else
    {
        if (MCHIP_QOS(lchip)->qos_sch_set_hsched && MCHIP_QOS(lchip)->qos_queue_write_hash_key)
        {
            CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, chan_id, group_id, 1, SYS_EXTEND_QUE_TYPE_C2C), ret, error0);
            CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_queue_write_hash_key(lchip, 0, chan_id, group_id, SYS_EXTEND_QUE_TYPE_C2C, 0, &key_index), ret, error1);
        }
    }
    if(!DRV_FROM_TMM(lchip))
    {
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
        if (NULL == p_sys_group_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            ret = CTC_E_NOT_EXIST;
            goto error2;
        }
        p_sys_group_node->chan_id  = chan_id;  /*0~63*/
    }
    p_c2c_que_node->lchip = lchip;
    p_c2c_que_node->type = SYS_EXTEND_QUE_TYPE_C2C;
    p_c2c_que_node->channel = chan_id;
    p_c2c_que_node->group_id = group_id;
    p_c2c_que_node->key_index = key_index;
    CTC_ERROR_GOTO(sys_usw_port_extender_add(lchip, p_c2c_que_node), ret, error2);

    if(!DRV_FROM_TMM(lchip))
    {
        /*network base queue*/
        CTC_ERROR_GOTO(sys_usw_queue_sch_set_c2c_group_sched(lchip, (chan_id * 8), 1), ret, error3);

        /*extend queue, 1 ext grp*/
        CTC_ERROR_GOTO(sys_usw_queue_sch_set_c2c_group_sched(lchip,
                                                             (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) + group_id*MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)), 3), ret, error3);

        /*disable to remote cpu/fromcpu ctl queue*/
        cmd = DRV_IOR(QWriteNetChannel_t, QWriteNetChannel_miscQueueDisable_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val), ret, error3);
        field_val = field_val | 0x4;
        cmd = DRV_IOW(QWriteNetChannel_t, QWriteNetChannel_miscQueueDisable_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val), ret, error3);
    }
    return CTC_E_NONE;

error3:
    c2c_que_node.type = SYS_EXTEND_QUE_TYPE_C2C;
    c2c_que_node.lchip = lchip;
    c2c_que_node.channel = chan_id;
    p_c2c_que_node = sys_usw_port_extender_lookup(lchip, &c2c_que_node);
    if (NULL == p_c2c_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    sys_usw_port_extender_remove(lchip, p_c2c_que_node);
error2:
    if(!DRV_FROM_TMM(lchip))
    {
        cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index , cmd, &cmd));
        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
        if (NULL == p_sys_group_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            ret = CTC_E_NOT_EXIST;
        }
        else
        {
            p_sys_group_node->chan_id  = 0xFF;
        }
    }
    else if (MCHIP_QOS(lchip)->qos_queue_del_hash_key)
    {
        MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, key_index);
    }
error1:
    if(!DRV_FROM_TMM(lchip))
    {
        _sys_usw_queue_free_key_index(lchip, 1, key_index);
    }
    else if (MCHIP_QOS(lchip)->qos_sch_set_hsched)
    {
        MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, chan_id, group_id, 0, SYS_EXTEND_QUE_TYPE_C2C);
    }
error0:
    if(p_usw_queue_master[lchip]->queue_num_per_stk_port == 0)
    {
        _sys_usw_queue_free_ext_group(lchip, 1, group_id);
    }
    mem_free(p_c2c_que_node);
    return ret;
}

uint32
_sys_usw_qos_set_group_default(uint8 lchip,uint16 group_id)
{
    uint32 cmd = 0;
    uint32 field_id = 0;
    uint32 field_val = 0;
    uint8  queue_offset = 0;
    uint8  step_meterSel = DsQMgrExtSchMap_que_1_meterSel_f - DsQMgrExtSchMap_que_0_meterSel_f;
    uint8  step_grpNodeSel = DsQMgrExtSchMap_que_1_grpNodeSel_f - DsQMgrExtSchMap_que_0_grpNodeSel_f;
    uint8  step_chanNodeSel = DsQMgrExtSchMap_grpNode_1_chanNodeSel_f - DsQMgrExtSchMap_grpNode_0_chanNodeSel_f;

    /*set default group sch class*/
    for(queue_offset = 0; queue_offset < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP); queue_offset++)
    {
        /* set default queue weight*/
        field_id = DsQMgrExtGrpWfqWeight_que_0_weight_f + queue_offset;
        field_val = 1;
        cmd = DRV_IOW(DsQMgrExtGrpWfqWeight_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
        /* set default group weight*/
        field_id = DsQMgrNetGrpSchWeight_node_0_weight_f + queue_offset;
        field_val = 1;
        cmd = DRV_IOW(DsQMgrNetGrpSchWeight_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id + MCHIP_CAP(SYS_CAP_QOS_BASE_QUEUE_GRP_NUM), cmd, &field_val));

        /* set default group sch*/
        field_id = DsQMgrExtSchMap_grpNode_0_chanNodeSel_f + step_chanNodeSel* queue_offset;
        field_val = 2;
        cmd = DRV_IOW(DsQMgrExtSchMap_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
        field_val = queue_offset;
        field_id = DsQMgrExtSchMap_que_0_grpNodeSel_f + step_grpNodeSel * queue_offset;
        cmd = DRV_IOW(DsQMgrExtSchMap_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
        field_id = DsQMgrExtSchMap_que_0_meterSel_f + step_meterSel * queue_offset;
        cmd = DRV_IOW(DsQMgrExtSchMap_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_check_queue_status(uint8 lchip, uint16 que_id)
{
    uint32 depth                   = 0;
    uint32 index                   = 0;
    uint32 cmd = 0;
    /*check queue flush clear*/

    do
    {
        cmd = DRV_IOR(DsErmQueueCnt_t,DsErmQueueCnt_queueCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, que_id, cmd, &depth));

        if(!depth)
        {
            return CTC_E_NONE;
        }
        sal_task_sleep(1);

    }while((index++) <= 1000);

    return CTC_E_HW_TIME_OUT;
}

int32
_sys_usw_check_port_status(uint8 lchip, uint16 chan_id)
{
    uint32 depth                   = 0;
    uint32 index                   = 0;
    uint32 cmd = 0;
    /*check queue flush clear*/

    do
    {
        cmd = DRV_IOR(DsErmPortCnt_t,DsErmPortCnt_portCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &depth));

        if(!depth)
        {
            return CTC_E_NONE;
        }
        sal_task_sleep(1);

    }while((index++) <= 1000);

    return CTC_E_HW_TIME_OUT;
}

/*for change binding relationship between extend queue group and port, will not discard pkt*/
uint32
_sys_usw_qos_flush_queue(uint8 lchip,uint16 chan_id,uint16 group_id,uint8 flag, uint16 queue_id)
{
    uint32 cmd = 0;
    uint8  queue_offset = 0;
    uint32 tokenThrd = 0;
    uint32 tokenThrdShift = 0;
    uint32 tokenRate = 0;
    uint32 field_val = 0;
    uint32 field_id = 0;
    int32 ret = 0;
    uint16 temp_queue_offset = 0;
    uint16 queue_offset_max = 0;
    DsQMgrNetChanShpProfile_m net_chan_shp_profile;

    if(MCHIP_QOS(lchip)->qos_queue_flush)
    {
        return MCHIP_QOS(lchip)->qos_queue_flush(lchip, chan_id, group_id, flag, queue_id);
    }
    temp_queue_offset = flag ? queue_id : 0;
    queue_offset_max = flag ? queue_id+1 : MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
    sal_memset(&net_chan_shp_profile, 0, sizeof(DsQMgrNetChanShpProfile_m));
    /*High group sch class*/
    for(queue_offset = 0; queue_offset < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP); queue_offset++)
    {
        field_id = DsQMgrExtSchMap_grpNode_0_chanNodeSel_f + queue_offset;
        field_val = 3;
        cmd = DRV_IOW(DsQMgrExtSchMap_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
    }
    /*Disable chan shaping*/
    cmd = DRV_IOR(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile),ret,error0);
    tokenThrd = GetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile);
    tokenThrdShift = GetDsQMgrNetChanShpProfile(V, tokenThrdShift_f, &net_chan_shp_profile);
    tokenRate = GetDsQMgrNetChanShpProfile(V, tokenRate_f, &net_chan_shp_profile);
    SetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD));
    SetDsQMgrNetChanShpProfile(V, tokenThrdShift_f  , &net_chan_shp_profile, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFT));
    SetDsQMgrNetChanShpProfile(V, tokenRate_f  , &net_chan_shp_profile, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE));
    cmd = DRV_IOW(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile),ret,error0);
    /*Disable extend group/queue shaping*/
    field_val = 0;
    cmd = DRV_IOW(DsQMgrExtGrpShpProfId_t, DsQMgrExtGrpShpProfId_profId_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val),ret,error1);
    for (queue_offset = temp_queue_offset; queue_offset < queue_offset_max; queue_offset++)
    {
        cmd = DRV_IOW(DsQMgrExtQueShpProfId_t, DsQMgrExtQueShpProfId_profId_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, (group_id*MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) + queue_offset), cmd, &field_val),ret,error1);
        CTC_ERROR_GOTO(_sys_usw_check_queue_status(lchip, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)+group_id*MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)+ queue_offset)),ret,error1);
    }
    /*Enable chan shaping*/
    cmd = DRV_IOR(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile),ret,error1);
    SetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile, tokenThrd);
    SetDsQMgrNetChanShpProfile(V, tokenThrdShift_f  , &net_chan_shp_profile, tokenThrdShift);
    SetDsQMgrNetChanShpProfile(V, tokenRate_f  , &net_chan_shp_profile, tokenRate);
    cmd = DRV_IOW(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile),ret,error1);
    /*set default group sch class*/
    CTC_ERROR_GOTO(_sys_usw_qos_set_group_default(lchip, group_id),ret,error0);

    return CTC_E_NONE;
error1:
    cmd = DRV_IOR(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile);
    SetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile, tokenThrd);
    SetDsQMgrNetChanShpProfile(V, tokenThrdShift_f  , &net_chan_shp_profile, tokenThrdShift);
    SetDsQMgrNetChanShpProfile(V, tokenRate_f  , &net_chan_shp_profile, tokenRate);
    cmd = DRV_IOW(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
    DRV_IOCTL(lchip, chan_id, cmd, &net_chan_shp_profile);
error0:
    _sys_usw_qos_set_group_default(lchip, group_id);

    return ret;
}
int32
_sys_usw_queue_remove_for_stacking(uint8 lchip, uint32 chan_id)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    DsQMgrGrpChanMap_m    grp_chan_map;
    sys_extend_que_node_t c2c_que_node;
    sys_extend_que_node_t* p_c2c_que_node = NULL;
    sys_queue_group_node_t *p_sys_group_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NONE;
    }
    sal_memset(&grp_chan_map, 0, sizeof(DsQMgrGrpChanMap_m));
    sal_memset(&c2c_que_node, 0, sizeof(sys_extend_que_node_t));

    c2c_que_node.type = SYS_EXTEND_QUE_TYPE_C2C;
    c2c_que_node.lchip = lchip;
    c2c_que_node.channel = chan_id;
    p_c2c_que_node = sys_usw_port_extender_lookup(lchip, &c2c_que_node);
    if (NULL == p_c2c_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }

    sys_usw_port_extender_remove(lchip, p_c2c_que_node);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);

    if (MCHIP_QOS(lchip)->qos_queue_del_hash_key)
    {
        CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_c2c_que_node->key_index));
    }
    else
    {
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        CTC_ERROR_RETURN(_sys_usw_queue_free_key_index(lchip, 1, p_c2c_que_node->key_index));
        cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_c2c_que_node->key_index , cmd, &cmd));
        SetDsQMgrGrpChanMap(V, channelId_f, &grp_chan_map, 0);
        cmd = DRV_IOW(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_c2c_que_node->group_id, cmd, &grp_chan_map));
    }

    if(p_usw_queue_master[lchip]->queue_num_per_stk_port == 0)
    {
        CTC_ERROR_RETURN(_sys_usw_queue_free_ext_group(lchip, 1, p_c2c_que_node->group_id));
    }
    if(!DRV_FROM_TMM(lchip))
    {
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, p_c2c_que_node->group_id);
        if (NULL == p_sys_group_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        p_sys_group_node->chan_id  = 0xFF;
    }
    if (MCHIP_QOS(lchip)->qos_sch_set_hsched)
    {
        CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, chan_id, p_c2c_que_node->group_id, 0, SYS_EXTEND_QUE_TYPE_C2C));
    }
    else
    {
        /*network base queue*/
        sys_usw_queue_sch_set_c2c_group_sched(lchip, (chan_id * 8), 2);

        /*extend queue, 1 ext grp*/
        sys_usw_queue_sch_set_c2c_group_sched(lchip, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) + p_c2c_que_node->group_id*MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)), 2);
    }
    mem_free(p_c2c_que_node);
    if(!DRV_FROM_TMM(lchip))
    {
        /*enable to remote cpu/fromcpu ctl queue*/
        cmd = DRV_IOR(QWriteNetChannel_t, QWriteNetChannel_miscQueueDisable_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));
        field_val = field_val & 0xB;
        cmd = DRV_IOW(QWriteNetChannel_t, QWriteNetChannel_miscQueueDisable_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));
    }
    return CTC_E_NONE;
}


uint32
_sys_usw_qos_write_queue_key(uint8 lchip, uint32 service_id, uint32 dest_port,
                                       uint16 logic_port,uint16 group_id,uint8 type,uint32* p_key_index,uint8 dir,uint16 service_flag)
{
    uint32 key_index = 0;
    tbl_entry_t   tcam_key;
    uint32 dest_map = 0;
    uint8  gchip = 0;
    uint32 cmd = 0;
    int32 ret = 0;
    uint16 lport = 0;
    uint8 xgpon_en = 0;
    DsQueueMapTcamData_m  QueueMapTcamData;
    DsQueueMapTcamKey_m   QueueMapTcamKey;
    DsQueueMapTcamKey_m   QueueMapTcamMask;

    sal_memset(&QueueMapTcamData, 0, sizeof(DsQueueMapTcamData_m));
    sal_memset(&QueueMapTcamKey, 0, sizeof(DsQueueMapTcamKey_m));
    sal_memset(&QueueMapTcamMask, 0, sizeof(DsQueueMapTcamKey_m));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dest_port, lchip, lport);
    CTC_ERROR_RETURN(_sys_usw_queue_alloc_key_index(lchip, 1, &key_index));

    SetDsQueueMapTcamData(V, extGroupId_f, &QueueMapTcamData, group_id);
    if(((dir == CTC_INGRESS && p_usw_queue_master[lchip]->service_queue_mode == 1)
        || (dir == CTC_EGRESS && p_usw_queue_master[lchip]->service_queue_mode == 2))
        && (service_flag & CTC_QOS_SERVICE_FLAG_QID_EN))
    {
        SetDsQueueMapTcamData(V, queueOffsetEn_f, &QueueMapTcamData, 1);
        SetDsQueueMapTcamData(V, queueOffset_f, &QueueMapTcamData, logic_port);
    }
    cmd = DRV_IOW(DsQueueMapTcamData_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index, cmd, &QueueMapTcamData), ret, error0);

    /*write tcam key*/
    sys_usw_get_gchip_id(lchip, &gchip);
    dest_map = SYS_ENCODE_DESTMAP(gchip, lport);
    SetDsQueueMapTcamKey(V, mcastIdValid_f, &QueueMapTcamKey, 0);
    SetDsQueueMapTcamKey(V, mcastIdValid_f, &QueueMapTcamMask, 1);
    SetDsQueueMapTcamKey(V, destChipIdMatch_f, &QueueMapTcamKey, 1);
    SetDsQueueMapTcamKey(V, destChipIdMatch_f, &QueueMapTcamMask, 1);
    SetDsQueueMapTcamKey(V, destMap_f, &QueueMapTcamKey, dest_map);
    SetDsQueueMapTcamKey(V, destMap_f, &QueueMapTcamMask, 0x1ff);
    SetDsQueueMapTcamKey(V, logicSrcPort_f, &QueueMapTcamKey, logic_port);
    SetDsQueueMapTcamKey(V, logicSrcPort_f, &QueueMapTcamMask, type ? 0 : 0xFFFF);
    if(dir == CTC_EGRESS)
    {
        sys_usw_global_get_xgpon_en(lchip, &xgpon_en);
        service_id = xgpon_en ? service_id : logic_port;
        SetDsQueueMapTcamKey(V, nexthopPtr_f, &QueueMapTcamKey, service_id);
        SetDsQueueMapTcamKey(V, nexthopPtr_f, &QueueMapTcamMask, 0xffff);
    }
    else
    {
        SetDsQueueMapTcamKey(V, serviceId_f, &QueueMapTcamKey, service_id);
        SetDsQueueMapTcamKey(V, serviceId_f, &QueueMapTcamMask, type ? 0x1ff : 0);

    }

    cmd = DRV_IOW(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
    tcam_key.data_entry = (uint32*)(&QueueMapTcamKey);
    tcam_key.mask_entry = (uint32*)(&QueueMapTcamMask);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index, cmd, &tcam_key), ret, error0);
    *p_key_index = key_index;

    return CTC_E_NONE;

error0:
    _sys_usw_queue_free_key_index(lchip, 1, key_index);

    return ret;
}

uint32
_sys_usw_qos_write_queue_key2(uint8 lchip, ctc_qos_service_info_t* p_service_para, uint16 group_id, uint32* p_key_index)
{
    uint32 key_index = 0;
    tbl_entry_t   tcam_key;
    uint32 dest_map = 0;
    uint8  gchip = 0;
    uint8  enq_by_key = !!(p_service_para->dsnh_offset_shift >> SYS_QOS_QUEUE_NH_OFFSET_OR_LOGIC_PORT_ENQ_SHIFT);
    uint32 cmd = 0;
    int32 ret = 0;
    uint32 nexthop_ptr = 0;
    uint32 nexthop_ptr_mask = 0;
    uint32 nomal_mask = p_service_para->dsnh_offset_shift ? ~((1 << p_service_para->dsnh_offset_shift) - 1) : 0xFFFF;
    uint16 lport = 0;
    uint16 service_id = 0;
    uint16 service_id_mask = 0;
    uint16 logic_src_port = 0;
    uint16 logic_src_port_mask = 0;
    DsQueueMapTcamData_m  QueueMapTcamData;
    DsQueueMapTcamKey_m   QueueMapTcamKey;
    DsQueueMapTcamKey_m   QueueMapTcamMask;

    CTC_PTR_VALID_CHECK(p_service_para);
    CTC_PTR_VALID_CHECK(p_key_index);
    sal_memset(&QueueMapTcamData, 0, sizeof(DsQueueMapTcamData_m));
    sal_memset(&QueueMapTcamKey, 0, sizeof(DsQueueMapTcamKey_m));
    sal_memset(&QueueMapTcamMask, 0, sizeof(DsQueueMapTcamKey_m));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_service_para->gport, lchip, lport);
    CTC_ERROR_RETURN(_sys_usw_queue_alloc_key_index(lchip, 1, &key_index));

    SetDsQueueMapTcamData(V, extGroupId_f, &QueueMapTcamData, group_id);

    /*write tcam key*/
    sys_usw_get_gchip_id(lchip, &gchip);
    dest_map = SYS_ENCODE_DESTMAP(gchip, lport);

    if (SYS_QUEUE_SERVICE_MODE_SERVICE_ID == p_service_para->mode)
    {
        service_id = p_service_para->service_id;
        service_id_mask = 0x1ff;
    }
    else if (SYS_QUEUE_SERVICE_MODE_LOGIC_PORT == p_service_para->mode)
    {
        logic_src_port = p_service_para->logic_port;
        logic_src_port_mask = 0xFFFF & nomal_mask;
    }
    else if (SYS_QUEUE_SERVICE_MODE_NH_OFFSET == p_service_para->mode)
    {
        if (p_usw_queue_master[lchip]->service_queue_mode == 0)
        {
            nexthop_ptr = p_service_para->logic_port;
            SetDsQueueMapTcamData(V, queueOffsetUseLogicDestPort_f, &QueueMapTcamData, enq_by_key);
        }
        else
        {
            nexthop_ptr = p_service_para->dsnh_offset;
            SetDsQueueMapTcamData(V, queueOffsetUseNexthopPtr_f, &QueueMapTcamData, enq_by_key);
        }
        nexthop_ptr_mask = 0x3FFFF & nomal_mask;
    }
    cmd = DRV_IOW(DsQueueMapTcamData_t, DRV_ENTRY_FLAG);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index, cmd, &QueueMapTcamData), ret, error0);

    SetDsQueueMapTcamKey(V, mcastIdValid_f, &QueueMapTcamKey, 0);
    SetDsQueueMapTcamKey(V, mcastIdValid_f, &QueueMapTcamMask, 1);
    SetDsQueueMapTcamKey(V, destChipIdMatch_f, &QueueMapTcamKey, 1);
    SetDsQueueMapTcamKey(V, destChipIdMatch_f, &QueueMapTcamMask, 1);
    SetDsQueueMapTcamKey(V, destMap_f, &QueueMapTcamKey, dest_map);
    SetDsQueueMapTcamKey(V, destMap_f, &QueueMapTcamMask, 0x1ff);
    SetDsQueueMapTcamKey(V, logicSrcPort_f, &QueueMapTcamKey, logic_src_port);
    SetDsQueueMapTcamKey(V, logicSrcPort_f, &QueueMapTcamMask, logic_src_port_mask);
    SetDsQueueMapTcamKey(V, nexthopPtr_f, &QueueMapTcamKey, nexthop_ptr);
    SetDsQueueMapTcamKey(V, nexthopPtr_f, &QueueMapTcamMask, nexthop_ptr_mask);
    SetDsQueueMapTcamKey(V, serviceId_f, &QueueMapTcamKey, service_id);
    SetDsQueueMapTcamKey(V, serviceId_f, &QueueMapTcamMask, service_id_mask);

    cmd = DRV_IOW(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
    tcam_key.data_entry = (uint32*)(&QueueMapTcamKey);
    tcam_key.mask_entry = (uint32*)(&QueueMapTcamMask);
    CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index, cmd, &tcam_key), ret, error0);
    *p_key_index = key_index;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "write queue tcam key, group id:%d, key index: %d\n", group_id, key_index);
    return CTC_E_NONE;

error0:
    _sys_usw_queue_free_key_index(lchip, 1, key_index);

    return ret;
}

STATIC int32
_sys_usw_qos_bind_service_dstport_queueid(uint8 lchip, uint32 service_id, uint32 dest_port,uint32 chan_id,uint16 queue_id,uint16 service_flag, ctc_qos_service_info_t* p_service_para)
{
    int32  ret = 0;
    uint32 group_id = 0;
    uint32 key_index = 0;
    uint16 lport = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dest_port, lchip, lport);
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if(p_service_que_node != NULL)
    {
        return CTC_E_EXIST;
    }

    p_service_que_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
    if (NULL == p_service_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_service_que_node, 0, sizeof(sys_extend_que_node_t));

    CTC_ERROR_GOTO(_sys_usw_queue_alloc_ext_queueid(lchip, service_id, dest_port, chan_id, CTC_INGRESS,queue_id, &group_id), ret, error0);

    p_service_que_node->service_id = service_id;
    p_service_que_node->lchip = lchip;
    p_service_que_node->lport = lport;
    p_service_que_node->type = SYS_EXTEND_QUE_TYPE_SERVICE;
    p_service_que_node->group_id = group_id;
    /* 8 bit is 1 means CTC_QOS_SERVICE_FLAG_QID_EN*/
    p_service_que_node->group_is_alloc = 0x81;
    p_service_que_node->queue_id = queue_id;
    CTC_ERROR_GOTO(sys_usw_port_extender_add(lchip, p_service_que_node), ret, error1);
    if (p_service_para)
    {
        CTC_ERROR_GOTO(_sys_usw_qos_write_queue_key2(lchip, p_service_para, group_id, &key_index), ret, error2);
    }
    else
    {
        CTC_ERROR_GOTO(_sys_usw_qos_write_queue_key(lchip, service_id,dest_port,(queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)),
                    p_service_que_node->group_id,1,&key_index, 0,service_flag),ret, error2);
    }
    p_service_que_node->key_index = key_index;
    return CTC_E_NONE;
error2:
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if (NULL == p_service_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        ret = CTC_E_NOT_EXIST;
    }
    else
    {
        sys_usw_port_extender_remove(lchip, p_service_que_node);
    }
error1:
    _sys_usw_queue_free_ext_queueid(lchip, service_id, dest_port, CTC_INGRESS);
error0:
    mem_free(p_service_que_node);
    return ret;
}

STATIC int32
_sys_usw_qos_unbind_service_dstport_queueid(uint8 lchip, uint32 service_id, uint32 dest_port,uint8 chan_id)
{
    uint32 cmd = 0;
    uint16 lport = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node ;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dest_port, lchip, lport);
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if(p_service_que_node == NULL)
    {
        return CTC_E_NOT_EXIST;
    }
    CTC_ERROR_RETURN(_sys_usw_queue_free_key_index(lchip, 1, p_service_que_node->key_index));
    cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_service_que_node->key_index, cmd, &cmd));
    _sys_usw_qos_flush_queue(lchip,chan_id,p_service_que_node->group_id,1,(p_service_que_node->queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)));
    _sys_usw_queue_free_ext_queueid(lchip, service_id, dest_port, CTC_INGRESS);
    sys_usw_port_extender_remove(lchip, p_service_que_node);
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_bind_service_dstport_oobfc(uint8 lchip, uint8 offset, uint32 group_id)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 index = 0;
    uint32 oobfc_group_num = 0;
    uint8 oobfc_is_pri = 0;

    cmd = DRV_IOR(QMgrOobFcCtl_t, QMgrOobFcCtl_oobFcPriEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
    oobfc_group_num = field_val ? 32 : 256;
    oobfc_is_pri = field_val ? 1 : 0;

    if(DRV_FROM_TMM(lchip))
    {
        /*alloc oobfc id*/
        for (index = 0; index < oobfc_group_num; index++)
        {
            if (!CTC_BMP_ISSET(p_usw_queue_master[lchip]->oobfc_group_info.fcid_bmp, index))
            {
                CTC_BMP_SET(p_usw_queue_master[lchip]->oobfc_group_info.fcid_bmp, index);
                field_val = oobfc_is_pri ? (index << 3) : index;
                cmd = DRV_IOW(DsQMgrGrpFlowCtlMap_t, DsQMgrGrpFlowCtlMap_oobFcId_f);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
                cmd = DRV_IOW(OobFcGrpMap_t, OobFcGrpMap_oobFcGrpMap_f);
                field_val = index;
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, offset, cmd, &field_val));

                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Group %d alloced oobfc id is %d\n", group_id, index);
                break;
            }
        }
        if(index == oobfc_group_num)
        {
            return CTC_E_NO_RESOURCE;
        }
        /*enable oobfc in group, bit0:normal fc, bit1:oobfc*/
        cmd = DRV_IOR(DsQMgrGrpConfig_t, DsQMgrGrpConfig_flowCtlEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
        field_val |= 0x2;
        cmd = DRV_IOW(DsQMgrGrpConfig_t, DsQMgrGrpConfig_flowCtlEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
    }
    else
    {
        CTC_MAX_VALUE_CHECK(group_id, p_usw_queue_master[lchip]->oobfc_group_info.group_base + oobfc_group_num - 1);

        if (!p_usw_queue_master[lchip]->oobfc_group_info.group_num)
        {
            field_val = group_id;
            cmd = DRV_IOW(QMgrOobFcCtl_t, QMgrOobFcCtl_oobFcGrpIdBase_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
            p_usw_queue_master[lchip]->oobfc_group_info.group_base = group_id;
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
        }
        field_val = group_id - p_usw_queue_master[lchip]->oobfc_group_info.group_base;
        cmd = DRV_IOW(OobFcGrpMap_t, OobFcGrpMap_oobFcGrpMap_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, offset, cmd, &field_val));
    }
    p_usw_queue_master[lchip]->oobfc_group_info.group_num ++;
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_unbind_service_dstport_oobfc(uint8 lchip, uint8 offset, uint32 group_id)
{
    uint32 cmd = 0;
    uint32 field_val = 0;

    if (DRV_FROM_TMM(lchip))
    {
        /*free oobfcid*/
        cmd = DRV_IOR(OobFcGrpMap_t, OobFcGrpMap_oobFcGrpMap_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, offset, cmd, &field_val));
        CTC_BMP_UNSET(p_usw_queue_master[lchip]->oobfc_group_info.fcid_bmp, field_val);

        field_val = 0;
        cmd = DRV_IOW(DsQMgrGrpFlowCtlMap_t, DsQMgrGrpFlowCtlMap_oobFcId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Group %d freed oobfc id is %d\n", group_id, field_val);
        /*enable oobfc in group, bit0:normal fc, bit1:oobfc*/
        cmd = DRV_IOR(DsQMgrGrpConfig_t, DsQMgrGrpConfig_flowCtlEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
        field_val &= 0x1;
        cmd = DRV_IOW(DsQMgrGrpConfig_t, DsQMgrGrpConfig_flowCtlEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
    }
    field_val = 0;
    cmd = DRV_IOW(OobFcGrpMap_t, OobFcGrpMap_oobFcGrpMap_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, offset, cmd, &field_val));

    if(!p_usw_queue_master[lchip]->oobfc_group_info.group_num)
    {
        return CTC_E_NONE;
    }
    p_usw_queue_master[lchip]->oobfc_group_info.group_num --;
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);

    if (!p_usw_queue_master[lchip]->oobfc_group_info.group_num)
    {
        cmd = DRV_IOW(QMgrOobFcCtl_t, QMgrOobFcCtl_oobFcGrpIdBase_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        p_usw_queue_master[lchip]->oobfc_group_info.group_base = 0;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
    }
    return CTC_E_NONE;
}

uint32
_sys_usw_qos_bind_service_dstport2_parm_check(uint8 lchip, ctc_qos_service_info_t* p_service_para, uint8 is_bind)
{
    uint32 dsnh_offset_shift = p_service_para->dsnh_offset_shift & ~(1 << SYS_QOS_QUEUE_NH_OFFSET_OR_LOGIC_PORT_ENQ_SHIFT);
    /*param check*/
    CTC_PTR_VALID_CHECK(p_service_para);
    CTC_MIN_VALUE_CHECK(p_service_para->service_id, 1);
    CTC_MAX_VALUE_CHECK(p_service_para->mode, SYS_QUEUE_SERVICE_MODE_MAX - 1);
    if(p_service_para->mode == SYS_QUEUE_SERVICE_MODE_SERVICE_ID)
    {
        if (1 != p_usw_queue_master[lchip]->service_queue_mode)
        {
            return CTC_E_NOT_SUPPORT;
        }
        CTC_MAX_VALUE_CHECK(p_service_para->dir, CTC_INGRESS);
        CTC_MAX_VALUE_CHECK(p_service_para->service_id, MCHIP_CAP(SYS_CAP_SERVICE_ID_NUM) - 1);
    }
    else if(p_service_para->mode == SYS_QUEUE_SERVICE_MODE_LOGIC_PORT
            || (p_service_para->mode == SYS_QUEUE_SERVICE_MODE_NH_OFFSET && 0 == p_usw_queue_master[lchip]->service_queue_mode))
    {
        if (is_bind)
        {
            CTC_VALUE_RANGE_CHECK(p_service_para->logic_port, 1, MCHIP_CAP(SYS_CAP_MAX_LOGIC_PORT));
        }
        CTC_MAX_VALUE_CHECK(dsnh_offset_shift, SYS_QOS_QUEUE_ENQ_LOGIC_PORT_WIDTH);
        if(p_service_para->dir != CTC_INGRESS)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid parameter \n");
            return CTC_E_INVALID_PARAM;
        }
    }
    else if(p_service_para->mode == SYS_QUEUE_SERVICE_MODE_NH_OFFSET)
    {
        if (is_bind)
        {
            CTC_VALUE_RANGE_CHECK(p_service_para->dsnh_offset, 1, (1 << SYS_QOS_QUEUE_ENQ_NH_OFFSET_WIDTH));
        }
        CTC_MAX_VALUE_CHECK(dsnh_offset_shift, SYS_QOS_QUEUE_ENQ_NH_OFFSET_WIDTH);
        if(DRV_IS_DUET2(lchip))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid parameter \n");
            return CTC_E_INVALID_PARAM;
        }
    }

    if((DRV_FROM_TMM(lchip) && (p_service_para->flag & CTC_QOS_SERVICE_FLAG_QID_EN)) || (p_service_para->flag & CTC_QOS_SERVICE_FLAG_OOBFC_EN))
    {
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}

STATIC uint32
_sys_usw_qos_service_update_erm_prof_id(uint8 lchip, uint32 chan_id, uint32 erm_prof_id)
{
    uint32 cmd = 0;

    cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &erm_prof_id));

    return CTC_E_NONE;
}

uint32
_sys_usw_qos_bind_service_dstport2(uint8 lchip, ctc_qos_service_info_t* p_service_para)
{
    int32  ret = 0;
    uint32 group_id = 0;
    uint32 key_index = 0;
    uint32 cmd = 0;
    uint32 chan_id = 0;
    uint16 lport = 0;
    uint8  gchip = 0;
    uint8  hsched_en = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node;
    sys_queue_group_node_t *p_sys_group_node = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }

    CTC_ERROR_RETURN(_sys_usw_qos_bind_service_dstport2_parm_check(lchip, p_service_para, 1));

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_service_para->gport, lchip, lport);
    dmps_port_info.gport = p_service_para->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    if(p_service_para->flag & CTC_QOS_SERVICE_FLAG_QID_EN)
    {
        CTC_MAX_VALUE_CHECK(p_service_para->queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) - MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) - 1));
        CTC_ERROR_RETURN(_sys_usw_qos_bind_service_dstport_queueid(lchip,p_service_para->service_id,p_service_para->gport,chan_id,p_service_para->queue_id,p_service_para->flag, p_service_para));
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
        return CTC_E_NONE;
    }

    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = p_service_para->service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    service_que_node.dir = p_service_para->dir;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if (NULL != p_service_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry exist \n");
        return CTC_E_EXIST;
    }

    p_service_que_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
    if (NULL == p_service_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_service_que_node, 0, sizeof(sys_extend_que_node_t));

    /*2.alloc queue group*/
    CTC_ERROR_GOTO(_sys_usw_queue_alloc_ext_group(lchip, 1, 1, &group_id), ret, error1);

    /*3.add to db*/
    p_service_que_node->type = SYS_EXTEND_QUE_TYPE_SERVICE;
    p_service_que_node->service_id = p_service_para->service_id;
    p_service_que_node->lchip = lchip;
    p_service_que_node->lport = lport;
    p_service_que_node->dir = p_service_para->dir;
    p_service_que_node->group_id = group_id;
    p_service_que_node->group_is_alloc = 1;
    CTC_ERROR_GOTO(sys_usw_port_extender_add(lchip, p_service_que_node), ret, error2);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);

    if (!DRV_FROM_TMM(lchip))
    {
        cmd = DRV_IOW(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, group_id, cmd, &chan_id), ret, error3);

        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
        if (NULL == p_sys_group_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            ret = CTC_E_NOT_EXIST;
            goto error3;
        }
        p_sys_group_node->chan_id  = chan_id;  /*0~63*/
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
    }

    if(MCHIP_QOS(lchip)->qos_sch_set_hsched && !CTC_FLAG_ISSET(p_service_para->flag, CTC_QOS_SERVICE_FLAG_HSCH_EN))
    {
        hsched_en = 1;
        CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, p_service_para->gport, p_service_que_node->group_id, 1, SYS_EXTEND_QUE_TYPE_SERVICE), ret, error3);
    }

    /*3.write tcam or hash key*/
    if (MCHIP_QOS(lchip)->qos_queue_write_hash_key)
    {
        DsQueueMap_m q_map;
        DsErmChannel_m erm_chan;
        uint32 service_mask = 0x7FFFF >> p_service_para->dsnh_offset_shift << p_service_para->dsnh_offset_shift;
        uint32 service_id_tmp = 0;
        uint32 erm_prof_id = 0;
        uint8 fromfabric = 0;
        uint8 qmaptype = 0;
        uint8 ext_type = 0;
        uint8 is_lsp = 0;
        uint8 i = 0;

        if (p_service_para->mode == SYS_QUEUE_SERVICE_MODE_SERVICE_ID)
        {
            ext_type = SYS_EXTEND_QUE_TYPE_SERVICE;
            service_id_tmp = p_service_para->service_id;
            erm_prof_id = SYS_ERM_PROFILE_DEFAULT;
        }
        else if (p_service_para->mode == SYS_QUEUE_SERVICE_MODE_LOGIC_PORT)
        {
            ext_type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
            service_id_tmp = p_service_para->logic_port;
            erm_prof_id = SYS_ERM_PROFILE_LOGIC_SRC_PORT_ENQ;
            is_lsp = 1;
        }
        else if (p_service_para->mode == SYS_QUEUE_SERVICE_MODE_NH_OFFSET && p_usw_queue_master[lchip]->service_queue_mode == 1)
        {
            ext_type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
            service_id_tmp = p_service_para->dsnh_offset;
            erm_prof_id = SYS_ERM_PROFILE_NH_GROUP;
        }
        else if (p_service_para->mode == SYS_QUEUE_SERVICE_MODE_NH_OFFSET && p_usw_queue_master[lchip]->service_queue_mode == 0)
        {
            /* use logic dest port enq and use nexthop ptr enq have same service type */
            ext_type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
            service_id_tmp = p_service_para->logic_port;
            erm_prof_id = SYS_ERM_PROFILE_NH_GROUP;
        }

        if (p_service_para->mode == SYS_QUEUE_SERVICE_MODE_NH_OFFSET || p_service_para->mode == SYS_QUEUE_SERVICE_MODE_LOGIC_PORT)
        {
            for (i = 0; i < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM); i++)
            {
                uint32 service_mask_tmp = 0;

                cmd = DRV_IOR(DsErmChannel_t, DRV_ENTRY_FLAG);
                CTC_ERROR_GOTO(DRV_IOCTL(lchip, i, cmd, &erm_chan), ret, error4);
                if (GetDsErmChannel(V, ermProfId_f, &erm_chan) == erm_prof_id)
                {
                    cmd = DRV_IOR(DsQueueMap_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, erm_prof_id, cmd, &q_map), ret, error4);
                    service_mask_tmp = GetDsQueueMap(V, serviceMask_f, &q_map);
                    if (service_mask_tmp != service_mask)
                    {
                        ret = CTC_E_INVALID_CONFIG;
                        goto error4;
                    }
                    break;
                }
            }

            service_id_tmp = service_id_tmp >> p_service_para->dsnh_offset_shift << p_service_para->dsnh_offset_shift;

            /* update service_mask, subject to the latest config */
            for (fromfabric = 0; fromfabric < 2; fromfabric++)
            {
                for (qmaptype = 0; qmaptype < SYS_QUE_MAP_TYPE_MAX_NUM; qmaptype++)
                {
                    uint8 index = fromfabric << 6 | qmaptype << 3 | erm_prof_id;

                    cmd = DRV_IOR(DsQueueMap_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, cmd, &q_map), ret, error4);
                    SetDsQueueMap(V, serviceMask_f, &q_map, service_mask);
                    cmd = DRV_IOW(DsQueueMap_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_GOTO(DRV_IOCTL(lchip, index, cmd, &q_map), ret, error4);
                }
            }
        }
        CTC_ERROR_GOTO(_sys_usw_qos_service_update_erm_prof_id(lchip, chan_id, erm_prof_id), ret, error4);
        CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_queue_write_hash_key(lchip, service_id_tmp, p_service_para->gport, group_id, ext_type, is_lsp, &key_index), ret, error4);
    }
    else
    {
        CTC_ERROR_GOTO(_sys_usw_qos_write_queue_key2(lchip, p_service_para, group_id, &key_index), ret, error4);
    }
    p_service_que_node->key_index = key_index;
    return CTC_E_NONE;
error4:
    if (hsched_en)
    {
        MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, p_service_para->gport, p_service_que_node->group_id, 0, SYS_EXTEND_QUE_TYPE_SERVICE);
    }
error3:
    if(p_service_que_node)
    {
        sys_usw_port_extender_remove(lchip, p_service_que_node);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
    }
error2:
    _sys_usw_queue_free_ext_group(lchip, 1, group_id);
error1:
    if (p_service_que_node)
    {
        mem_free(p_service_que_node);
    }
    return ret;
}

uint32
_sys_usw_qos_unbind_service_dstport2(uint8 lchip, ctc_qos_service_info_t* p_service_para)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32  chan_id = 0;
    uint16 lport = 0;
    uint16 group_idx = 0;
    uint8  gchip = 0;
    uint8  bind_group = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node;
    sys_queue_group_node_t *p_sys_group_node = NULL;
    sys_sch_group_node_t *p_sch_group_node = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }

    CTC_ERROR_RETURN(_sys_usw_qos_bind_service_dstport2_parm_check(lchip, p_service_para, 0));

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(p_service_para->gport, lchip, lport);
    dmps_port_info.gport = p_service_para->gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    if(p_service_para->flag & CTC_QOS_SERVICE_FLAG_QID_EN)
    {
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
        CTC_ERROR_RETURN(_sys_usw_qos_unbind_service_dstport_queueid(lchip,p_service_para->service_id,p_service_para->gport,chan_id));
        return CTC_E_NONE;
    }

    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));

    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = p_service_para->service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    service_que_node.dir = p_service_para->dir;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if (NULL == p_service_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }

    if (MCHIP_QOS(lchip)->qos_queue_del_hash_key)
    {
        MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_service_que_node->key_index);
    }
    else
    {
        _sys_usw_queue_free_key_index(lchip, 1, p_service_que_node->key_index);
        cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        DRV_IOCTL(lchip, p_service_que_node->key_index, cmd, &cmd);
    }

    _sys_usw_qos_flush_queue(lchip,chan_id,p_service_que_node->group_id,0,0);
    _sys_usw_queue_free_ext_group(lchip, 1, p_service_que_node->group_id);
    if (MCHIP_QOS(lchip)->qos_sch_set_hsched && !CTC_FLAG_ISSET(p_service_para->flag,CTC_QOS_SERVICE_FLAG_HSCH_EN))
    {
        MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, p_service_para->gport, p_service_que_node->group_id, 0, SYS_EXTEND_QUE_TYPE_SERVICE);
    }

    if(!DRV_FROM_TMM(lchip))
    {
        field_val = 0;
        cmd = DRV_IOW(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
        DRV_FIELD_IOCTL(lchip, p_service_que_node->group_id, cmd, &field_val);

        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, p_service_que_node->group_id);
        if (NULL == p_sys_group_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        p_sys_group_node->chan_id  = 0xFF;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
    }
    else
    {
        /* reset erm profile id */
        for (group_idx = MCHIP_CAP(SYS_CAP_CHANNEL_NUM)-1; group_idx < MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM); group_idx++)
        {
            p_sch_group_node = ctc_vector_get(p_usw_queue_master[lchip]->sch_group_vec, group_idx);
            if (NULL == p_sch_group_node || 0 == p_sch_group_node->chan_valid || MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0) == p_sch_group_node->chan_id)
            {
                continue;
            }
            if (chan_id == p_sch_group_node->chan_id)
            {
                bind_group = 1;
                break;
            }
        }
        if (0 == bind_group)
        {
            CTC_ERROR_RETURN(_sys_usw_qos_service_update_erm_prof_id(lchip, chan_id, SYS_ERM_PROFILE_DEFAULT));
        }
    }

    sys_usw_port_extender_remove(lchip, p_service_que_node);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
    mem_free(p_service_que_node);

    return CTC_E_NONE;
}

uint32
_sys_usw_qos_bind_service_dstport(uint8 lchip, uint32 service_id, uint32 dest_port,uint16 logic_port,uint8 dir,
                                                uint32 nexthop_ptr,uint16 queue_id,uint8 offset,uint16 service_flag)
{
    ctc_slistnode_t* ctc_slistnode = NULL;
    int32  ret = 0;
    uint32 group_id = 0;
    uint32 key_index = 0;
    uint32 cmd = 0;
    uint32  chan_id = 0;
    uint16 lport = 0;
    uint16 value_tmp = 0;
    uint8  gchip = 0;
    uint8  first_add = 0;
    uint8  flag = 0;
    uint8 xgpon_en = 0;
    uint8 hsched_en = 0;
    uint32 service_id_tmp = 0;
    sys_service_node_t* p_service = NULL;
    sys_service_node_t service;
    sys_qos_destport_t* p_dest_port_node = NULL;
    sys_qos_logicport_t* p_logic_port_node = NULL;
    DsQMgrGrpChanMap_m    grp_chan_map;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node, *p_logice_que_node ;
    sys_queue_group_node_t *p_sys_group_node = NULL;
    sys_extend_que_node_t* p_service_que_logic_node = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }

    sal_memset(&grp_chan_map, 0, sizeof(DsQMgrGrpChanMap_m));
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    sal_memset(&service, 0, sizeof(sys_service_node_t));

    CTC_MIN_VALUE_CHECK(service_id, 1);
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    sys_usw_global_get_xgpon_en(lchip, &xgpon_en);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dest_port, lchip, lport);
    dmps_port_info.gport = dest_port;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    if(dir == CTC_INGRESS && p_usw_queue_master[lchip]->service_queue_mode == 1)
    {
        CTC_VALUE_RANGE_CHECK(service_id, 1, MCHIP_CAP(SYS_CAP_SERVICE_ID_NUM) - 1);
    }
    if((DRV_FROM_TMM(lchip)
        || !((dir == CTC_INGRESS && p_usw_queue_master[lchip]->service_queue_mode == 1)
        || (dir == CTC_EGRESS && p_usw_queue_master[lchip]->service_queue_mode == 2))
        || (service_flag & CTC_QOS_SERVICE_FLAG_OOBFC_EN))
        && (service_flag & CTC_QOS_SERVICE_FLAG_QID_EN))
    {
        return CTC_E_NOT_SUPPORT;
    }
    /* xgpon support queue offset ad */
    if(dir == CTC_INGRESS && (service_flag & CTC_QOS_SERVICE_FLAG_QID_EN) && p_usw_queue_master[lchip]->service_queue_mode == 1)
    {
        CTC_MAX_VALUE_CHECK(queue_id, (MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT) - MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) - 1));
        CTC_ERROR_RETURN(_sys_usw_qos_bind_service_dstport_queueid(lchip,service_id,dest_port,chan_id,queue_id,service_flag, NULL));
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
        return CTC_E_NONE;
    }
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    if(dir == CTC_EGRESS)
    {
        CTC_MIN_VALUE_CHECK(service_id, 1);
        if(p_usw_queue_master[lchip]->service_queue_mode != 2 && xgpon_en != 1)
        {
            return CTC_E_NOT_SUPPORT;
        }
        service_que_node.lport = lport;
        service_que_node.dir = CTC_INGRESS;
        p_service_que_logic_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
        if (NULL != p_service_que_logic_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry exist \n");
            return CTC_E_EXIST;
        }
    }
    else
    {
        service_que_node.lport = lport;
        service_que_node.dir = CTC_EGRESS;
        p_service_que_logic_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
        if (NULL != p_service_que_logic_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry exist \n");
            return CTC_E_EXIST;
        }
    }
    service_que_node.dir = dir;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if (NULL == p_service_que_node)
    {
        first_add = 1;
        p_service_que_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
        if (NULL == p_service_que_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
            return CTC_E_NO_MEMORY;
        }
        sal_memset(p_service_que_node, 0, sizeof(sys_extend_que_node_t));

        if(service_flag & CTC_QOS_SERVICE_FLAG_QID_EN)
        {
            ret = _sys_usw_queue_alloc_ext_queueid(lchip, service_id, dest_port,chan_id,dir, queue_id, &group_id);
        }
        else
        {
            ret = _sys_usw_queue_alloc_ext_group(lchip, 1, 1, &group_id);
        }
        if (ret < 0)
        {
            mem_free(p_service_que_node);
            return ret;
        }
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        p_service_que_node->service_id = service_id;
        p_service_que_node->lchip = lchip;
        p_service_que_node->lport = lport;
        p_service_que_node->dir = dir;
        p_service_que_node->type = SYS_EXTEND_QUE_TYPE_SERVICE;
        p_service_que_node->group_id = group_id;
        p_service_que_node->queue_id = service_flag & CTC_QOS_SERVICE_FLAG_QID_EN ? queue_id : 0;
        if(dir == CTC_EGRESS)
        {
            p_service_que_node->group_is_alloc = service_flag & CTC_QOS_SERVICE_FLAG_QID_EN ? 0x81 : 1;
        }
        CTC_ERROR_GOTO(sys_usw_port_extender_add(lchip, p_service_que_node), ret, error0);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);

        if (!DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOW(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, group_id, cmd, &chan_id), ret, error0);

            p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
            if (NULL == p_sys_group_node)
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                ret = CTC_E_NOT_EXIST;
                goto error1;
            }
            p_sys_group_node->chan_id  = chan_id;  /*0~63*/
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        }
        if(MCHIP_QOS(lchip)->qos_sch_set_hsched && !CTC_FLAG_ISSET(service_flag, CTC_QOS_SERVICE_FLAG_HSCH_EN))
        {
            hsched_en = 1;
            CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, dest_port, p_service_que_node->group_id, 1, SYS_EXTEND_QUE_TYPE_SERVICE), ret, error2);
        }
        if(dir == CTC_EGRESS)
        {
            return CTC_E_NONE;
        }
    }
    else if(p_service_que_node != NULL && logic_port != 0&& dir == CTC_EGRESS)
    {
        /*1. logic dest port + service id has bind, service id + dest port has bind
          2. doing update logic dest port + service id bind*/
        if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_write_hash_key)
        {
            uint8 ext_type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
            service_id_tmp = xgpon_en ? p_service_que_node->logic_dst_port : nexthop_ptr;
            CTC_ERROR_RETURN(_sys_usw_qos_service_update_erm_prof_id(lchip, chan_id, SYS_ERM_PROFILE_NH_GROUP));
            CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_queue_write_hash_key(lchip, service_id_tmp, dest_port, p_service_que_node->group_id, ext_type, 0, &key_index));
        }
        else
        {
            value_tmp = service_flag & CTC_QOS_SERVICE_FLAG_QID_EN ? (p_service_que_node->queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)) : nexthop_ptr;
            CTC_ERROR_RETURN(_sys_usw_qos_write_queue_key(lchip, logic_port,dest_port,value_tmp,p_service_que_node->group_id,1,&key_index, dir,service_flag));
        }
        p_service_que_node->logic_dst_port = logic_port;
        p_service_que_node->nexthop_ptr = nexthop_ptr;
        p_service_que_node->group_is_alloc = service_flag & CTC_QOS_SERVICE_FLAG_QID_EN ? 0x81 : 1;
        p_service_que_node->key_index = key_index;
        return CTC_E_NONE;
    }
    else if(p_service_que_node != NULL  &&p_service_que_node->logic_dst_port!= 0&& dir == CTC_EGRESS)
    {
        /*1. logic dest port + service id has bind
          2. doing service id + dest port bind*/
        flag = 1;
        if(p_service_que_node->group_is_alloc || p_service_que_node->lport != lport)
        {
            return CTC_E_EXIST;
        }
        if(service_flag & CTC_QOS_SERVICE_FLAG_QID_EN)
        {
            CTC_ERROR_RETURN(_sys_usw_queue_alloc_ext_queueid(lchip, service_id, dest_port,chan_id,dir, queue_id, &group_id));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_usw_queue_alloc_ext_group(lchip, 1, 1, &group_id));
        }
        if(MCHIP_QOS(lchip)->qos_sch_set_hsched && !CTC_FLAG_ISSET(service_flag, CTC_QOS_SERVICE_FLAG_HSCH_EN))
        {
            hsched_en = 1;
            CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, dest_port, group_id, 1, SYS_EXTEND_QUE_TYPE_SERVICE), ret, error0);
        }
        if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_write_hash_key)
        {
            uint8 ext_type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
            service_id_tmp = xgpon_en ? p_service_que_node->logic_dst_port : p_service_que_node->nexthop_ptr;
            CTC_ERROR_GOTO(_sys_usw_qos_service_update_erm_prof_id(lchip, chan_id, SYS_ERM_PROFILE_NH_GROUP), ret, error2);
            CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_queue_write_hash_key(lchip, service_id_tmp, dest_port, group_id, ext_type, 0, &key_index), ret, error2);
        }
        else
        {
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
            cmd = DRV_IOW(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, group_id, cmd, &chan_id), ret, error0);
            p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
            if (NULL == p_sys_group_node)
            {
                 SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                 ret = CTC_E_NOT_EXIST;
                 goto error0;
            }
            p_sys_group_node->chan_id  = chan_id;  /*0~63*/
            value_tmp = service_flag & CTC_QOS_SERVICE_FLAG_QID_EN ? (queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)) : p_service_que_node->nexthop_ptr;
            CTC_ERROR_GOTO(_sys_usw_qos_write_queue_key(lchip, p_service_que_node->logic_dst_port,dest_port,value_tmp,group_id,1,&key_index, dir,service_flag), ret, error2);
        }
        p_service_que_node->group_is_alloc = service_flag & CTC_QOS_SERVICE_FLAG_QID_EN ? 0x81 : 1;
        p_service_que_node->group_id = group_id;
        p_service_que_node->key_index = key_index;
        p_service_que_node->queue_id = service_flag & CTC_QOS_SERVICE_FLAG_QID_EN ? queue_id : 0;
        return CTC_E_NONE;
    }
    else if (p_service_que_node != NULL  &&p_service_que_node->logic_dst_port == 0&& dir == CTC_EGRESS)
    {
        /*1. service id + dest port bind
          2. doing update service id + dest port bind*/
        return CTC_E_NONE;
    }
    else
    {
        if(p_usw_queue_master[lchip]->service_queue_mode == 1 ||logic_port == 0)
        { /*service id based queue*/
            return CTC_E_EXIST;
        }
    }
    service_id_tmp = service_id;
    if(p_usw_queue_master[lchip]->service_queue_mode == 1)
    {
        if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_write_hash_key)
        {
            uint8 ext_type = SYS_EXTEND_QUE_TYPE_SERVICE;
            CTC_ERROR_GOTO(_sys_usw_qos_service_update_erm_prof_id(lchip, chan_id, SYS_ERM_PROFILE_DEFAULT), ret, error2);
            CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_queue_write_hash_key(lchip, service_id_tmp, dest_port, group_id, ext_type, 0, &key_index), ret, error2);
        }
        else
        {
            CTC_ERROR_GOTO(_sys_usw_qos_write_queue_key(lchip, service_id_tmp,dest_port,logic_port,group_id,1,&key_index, dir,0),ret,error2);
        }
        p_service_que_node->key_index = key_index;
    }
    else
    {
        service.service_id = service_id;
        p_service = sys_usw_service_lookup(lchip, &service);
        if (NULL == p_service)
        {
            ret = CTC_E_NOT_EXIST;
            goto error2;
        }
        /*new logic*/
        CTC_SLIST_LOOP(p_service->p_logic_port_list, ctc_slistnode)
        {
            p_logic_port_node = _ctc_container_of(ctc_slistnode, sys_qos_logicport_t, head);
            if(logic_port == 0 || logic_port == p_logic_port_node->logic_port)
            {
                p_logice_que_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
                if (NULL == p_logice_que_node)
                {
                    ret = CTC_E_NO_MEMORY;
                    goto error4;
                }
                sal_memset(p_logice_que_node, 0, sizeof(sys_extend_que_node_t));
                if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_write_hash_key)
                {
                    uint8 ext_type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
                    CTC_ERROR_GOTO(_sys_usw_qos_service_update_erm_prof_id(lchip, chan_id, SYS_ERM_PROFILE_LOGIC_SRC_PORT_ENQ), ret, error4);
                    CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_queue_write_hash_key(lchip, p_logic_port_node->logic_port, dest_port, p_service_que_node->group_id, ext_type, 1, &key_index), ret, error4);
                }
                else
                {
                    CTC_ERROR_GOTO(_sys_usw_qos_write_queue_key(lchip, service_id_tmp,dest_port,p_logic_port_node->logic_port,p_service_que_node->group_id,0,&key_index, dir,0),ret,error4);
                }
                SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);

                p_logice_que_node->logic_src_port = p_logic_port_node->logic_port;
                p_logice_que_node->service_id = service_id;
                p_logice_que_node->lport = lport;
                p_logice_que_node->lchip = lchip;
                p_logice_que_node->type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
                p_logice_que_node->key_index = key_index;
                CTC_ERROR_GOTO(sys_usw_port_extender_add(lchip, p_logice_que_node),ret,error4);
            }
        }

        if(logic_port == 0)
        {
            /*bind new dest port */
            p_dest_port_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_destport_t));
            if (NULL == p_dest_port_node)
            {
                ret = CTC_E_NO_MEMORY;
                goto error4;
            }
            sal_memset(p_dest_port_node, 0, sizeof(sys_qos_destport_t));
            p_dest_port_node->lchip= lchip;
            p_dest_port_node->lport = lport;
            ctc_slist_add_tail(p_service->p_dest_port_list, &p_dest_port_node->head);
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_DESTPORT, 1);
        }
    }

    if (service_flag & CTC_QOS_SERVICE_FLAG_OOBFC_EN)
    {
        OobFcCfgNum_m cfg_num;
        CTC_ERROR_GOTO(_sys_usw_qos_bind_service_dstport_oobfc(lchip, offset, group_id), ret, error3);

        cmd = DRV_IOR(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
        SetOobFcCfgNum(V, cfgPortNum_f, &cfg_num, p_usw_queue_master[lchip]->oobfc_group_info.group_num - 1);
        cmd = DRV_IOW(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
    }
    return CTC_E_NONE;

error4:
    CTC_SLIST_LOOP(p_service->p_logic_port_list, ctc_slistnode)
    {
        p_logic_port_node = _ctc_container_of(ctc_slistnode, sys_qos_logicport_t, head);
        if(logic_port == 0 || logic_port == p_logic_port_node->logic_port)
        {
            sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
            service_que_node.type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
            service_que_node.logic_src_port = p_logic_port_node->logic_port;
            service_que_node.service_id = service_id;
            service_que_node.lchip = lchip;
            service_que_node.lport = lport;
            p_logice_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
            if(p_logice_que_node)
            {
                sys_usw_port_extender_remove(lchip, p_logice_que_node);
                SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
                if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_del_hash_key)
                {
                    MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_service_que_node->key_index);
                }
                else
                {
                    _sys_usw_queue_free_key_index(lchip, 1, p_logice_que_node->key_index);
                    cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
                    DRV_IOCTL(lchip, p_logice_que_node->key_index, cmd, &cmd);
                }
                mem_free(p_logice_que_node);
            }
        }
    }
error3:
    if (p_usw_queue_master[lchip]->service_queue_mode == 1 &&
        CTC_FLAG_ISSET(service_flag, CTC_QOS_SERVICE_FLAG_OOBFC_EN))
    {
        if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_del_hash_key)
        {
            MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, key_index);
        }
    }
error2:
    if((first_add || flag) && (!DRV_FROM_TMM(lchip)))
    {
        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
        if (NULL == p_sys_group_node)
        {
             SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
             ret = CTC_E_NOT_EXIST;
        }
        else
        {
            p_sys_group_node->chan_id  = 0xff;  /*0~63*/
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        }
    }

    if(hsched_en && MCHIP_QOS(lchip)->qos_sch_set_hsched && !CTC_FLAG_ISSET(service_flag, CTC_QOS_SERVICE_FLAG_HSCH_EN))
    {
        MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, dest_port, p_service_que_node->group_id, 0, SYS_EXTEND_QUE_TYPE_SERVICE);
    }
error1:
    if(first_add)
    {
        sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
        service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
        service_que_node.service_id = service_id;
        service_que_node.lchip = lchip;
        service_que_node.lport = lport;
        service_que_node.dir = dir;
        p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
        if (NULL == p_service_que_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            ret = CTC_E_NOT_EXIST;
        }
        sys_usw_port_extender_remove(lchip, p_service_que_node);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
    }
error0:
    if(first_add || flag)
    {
        _sys_usw_queue_free_ext_group(lchip, 1, group_id);
        if(first_add)
        {
            mem_free(p_service_que_node);
        }

        if(!DRV_FROM_TMM(lchip))
        {
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        }

    }
    return ret;
}

uint32
_sys_usw_qos_unbind_service_dstport(uint8 lchip, uint32 service_id, uint32 dest_port, uint16 logic_port, uint8 dir,
                                    uint8 offset, uint16 service_flag)
{
    sys_service_node_t* p_service = NULL;
    sys_service_node_t service;
    sys_qos_destport_t* p_dest_port_node = NULL;
    sys_qos_logicport_t* p_logic_port_node = NULL;
    ctc_slistnode_t* node , *next_node;
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32  chan_id = 0;
    uint16 lport = 0;
    uint8  gchip = 0;
    uint8 xgpon_en = 0;
    DsQMgrGrpChanMap_m    grp_chan_map;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node = NULL ;
    sys_extend_que_node_t* p_logice_que_node = NULL;
    sys_queue_group_node_t *p_sys_group_node = NULL;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }
    sal_memset(&grp_chan_map, 0, sizeof(DsQMgrGrpChanMap_m));
    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    sys_usw_global_get_xgpon_en(lchip, &xgpon_en);
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dest_port, lchip, lport);
    dmps_port_info.gport = dest_port;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    if(p_usw_queue_master[lchip]->service_queue_mode != 2&& dir == CTC_EGRESS && xgpon_en != 1)
    {
        return CTC_E_NOT_SUPPORT;
    }
    if((DRV_FROM_TMM(lchip)
        || !((dir == CTC_INGRESS && p_usw_queue_master[lchip]->service_queue_mode == 1)
        || (dir == CTC_EGRESS && p_usw_queue_master[lchip]->service_queue_mode == 2))
        || (service_flag & CTC_QOS_SERVICE_FLAG_OOBFC_EN))
        && (service_flag & CTC_QOS_SERVICE_FLAG_QID_EN))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if(dir == CTC_INGRESS && p_usw_queue_master[lchip]->service_queue_mode == 1 && (service_flag & CTC_QOS_SERVICE_FLAG_QID_EN))
    {
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
        CTC_ERROR_RETURN(_sys_usw_qos_unbind_service_dstport_queueid(lchip,service_id,dest_port,chan_id));
        return CTC_E_NONE;
    }
    if (0 == logic_port)
    {
        service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
        service_que_node.service_id = service_id;
        service_que_node.lchip = lchip;
        service_que_node.lport = lport;
        service_que_node.dir = dir;
        p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
        if (NULL == p_service_que_node || (dir == CTC_EGRESS && !p_service_que_node->group_is_alloc))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        if(DRV_FROM_TMM(lchip) && (CTC_FLAG_ISSET(service_flag, CTC_QOS_SERVICE_FLAG_HSCH_EN)))
        {
            ctc_qos_sched_group_t group_sched;
            sal_memset(&group_sched, 0, sizeof(ctc_qos_sched_group_t));
            SYS_SUB_GRP_TO_LVL_GRP(group_sched.group_id, CTC_QOS_SCHED_GROUP_LVL_Q, lchip, p_service_que_node->group_id);
            sys_usw_queue_sch_get_group_sched(lchip, 0, &group_sched);
            if(group_sched.parent_id != 0)
            {
                return CTC_E_INVALID_CONFIG;
            }
        }
    }
    if(p_usw_queue_master[lchip]->service_queue_mode == 0 || (p_usw_queue_master[lchip]->service_queue_mode == 2 && dir == CTC_INGRESS))
    {
        sal_memset(&service, 0, sizeof(service));
        service.service_id = service_id;
        p_service = sys_usw_service_lookup(lchip, &service);
        if (NULL == p_service)
        {
            return CTC_E_NOT_EXIST;
        }
        CTC_SLIST_LOOP_DEL(p_service->p_logic_port_list, node, next_node)
        {/*service_queue_mode == 0*/
            p_logic_port_node = _ctc_container_of(node, sys_qos_logicport_t, head);
            if(logic_port == 0 || logic_port == p_logic_port_node->logic_port)
            {
                sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
                service_que_node.service_id = service_id;
                service_que_node.logic_src_port = p_logic_port_node->logic_port;
                service_que_node.lport = lport;
                service_que_node.lchip = lchip;
                service_que_node.type = SYS_EXTEND_QUE_TYPE_LOGIC_PORT;
                p_logice_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
                if (!p_logice_que_node)
                {
                    continue;
                }
                if (MCHIP_QOS(lchip)->qos_queue_del_hash_key)
                {
                    MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_logice_que_node->key_index);
                }
                else
                {
                    _sys_usw_queue_free_key_index(lchip, 1, p_logice_que_node->key_index);
                    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
                    cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
                    DRV_IOCTL(lchip, p_logice_que_node->key_index, cmd, &cmd);
                }
                if(DRV_FROM_TMM(lchip) && p_usw_queue_master[lchip]->service_queue_mode == 2)
                {
                    field_val = xgpon_en ? SYS_ERM_PROFILE_NH_GROUP : SYS_ERM_PROFILE_DEFAULT;
                    cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, chan_id, cmd, &field_val));
                }
                sys_usw_port_extender_remove(lchip, p_logice_que_node);
                mem_free(p_logice_que_node);
            }
        }
    }
    if( logic_port != 0)
    { /*service_queue_mode == 0*/
       return CTC_E_NONE;
    }

    if(dir == CTC_EGRESS)
    {
        if(p_service_que_node->logic_dst_port != 0)
        {
            if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_del_hash_key)
            {
                MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_service_que_node->key_index);
            }
            else
            {
                CTC_ERROR_RETURN(_sys_usw_queue_free_key_index(lchip, 1, p_service_que_node->key_index));
                cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_service_que_node->key_index, cmd, &cmd));
            }
            p_service_que_node->group_is_alloc = 0;
        }
        if (service_flag & CTC_QOS_SERVICE_FLAG_QID_EN)
        {
            _sys_usw_qos_flush_queue(lchip,chan_id,p_service_que_node->group_id,1,(p_service_que_node->queue_id%MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP)));
            _sys_usw_queue_free_ext_queueid(lchip, service_id, dest_port, dir);
        }
        else
        {
            _sys_usw_qos_flush_queue(lchip,chan_id,p_service_que_node->group_id,0,0);
            _sys_usw_queue_free_ext_group(lchip, 1, p_service_que_node->group_id);
        }
        if (MCHIP_QOS(lchip)->qos_sch_set_hsched && !CTC_FLAG_ISSET(service_flag, CTC_QOS_SERVICE_FLAG_HSCH_EN))
        {
            MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, dest_port, p_service_que_node->group_id, 0, SYS_EXTEND_QUE_TYPE_SERVICE);
        }
        if(!DRV_FROM_TMM(lchip))
        {
            chan_id = 0;
            SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
            SetDsQMgrGrpChanMap(V, channelId_f, &grp_chan_map, chan_id);
            cmd = DRV_IOW(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_service_que_node->group_id, cmd, &grp_chan_map));
            p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, p_service_que_node->group_id);
            if (NULL == p_sys_group_node)
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                return CTC_E_NOT_EXIST;
            }
            p_sys_group_node->chan_id  = 0xFF;
        }
        sys_usw_port_extender_remove(lchip, p_service_que_node);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
        mem_free(p_service_que_node);
        return CTC_E_NONE;
    }
    sys_usw_port_extender_remove(lchip, p_service_que_node);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
    if(p_usw_queue_master[lchip]->service_queue_mode == 1)
    {
        if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_del_hash_key)
        {
            MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_service_que_node->key_index);
        }
        else
        {
            CTC_ERROR_RETURN(_sys_usw_queue_free_key_index(lchip, 1, p_service_que_node->key_index));
            cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_service_que_node->key_index, cmd, &cmd));
        }
    }
    else
    {
        CTC_SLIST_LOOP(p_service->p_dest_port_list, node)
        {
            p_dest_port_node = _ctc_container_of(node, sys_qos_destport_t, head);
            if (p_dest_port_node->lchip == lchip && p_dest_port_node->lport == lport)
            {
                break;
            }
        }
        ctc_slist_delete_node(p_service->p_dest_port_list, &p_dest_port_node->head);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_DESTPORT, 1);
        mem_free(p_dest_port_node);
    }
    _sys_usw_qos_flush_queue(lchip,chan_id,p_service_que_node->group_id,0,0);
    _sys_usw_queue_free_ext_group(lchip, 1, p_service_que_node->group_id);
    if (MCHIP_QOS(lchip)->qos_sch_set_hsched && !CTC_FLAG_ISSET(service_flag, CTC_QOS_SERVICE_FLAG_HSCH_EN))
    {
        MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, dest_port, p_service_que_node->group_id, 0, SYS_EXTEND_QUE_TYPE_SERVICE);
    }
    if (!DRV_FROM_TMM(lchip))
    {
        chan_id = 0;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
        SetDsQMgrGrpChanMap(V, channelId_f, &grp_chan_map, chan_id);
        cmd = DRV_IOW(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_service_que_node->group_id, cmd, &grp_chan_map));
        p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, p_service_que_node->group_id);
        if (NULL == p_sys_group_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        p_sys_group_node->chan_id  = 0xFF;
    }

    if (service_flag & CTC_QOS_SERVICE_FLAG_OOBFC_EN)
    {
        OobFcCfgNum_m cfg_num;
        _sys_usw_qos_unbind_service_dstport_oobfc(lchip, offset, p_service_que_node->group_id);

        cmd = DRV_IOR(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
        SetOobFcCfgNum(V, cfgPortNum_f, &cfg_num, p_usw_queue_master[lchip]->oobfc_group_info.group_num - 1);
        cmd = DRV_IOW(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
    }
    mem_free(p_service_que_node);

    return CTC_E_NONE;
}

int32
_sys_usw_qos_bind_service_logic_dstport(uint8 lchip, uint16 service_id, uint16 logic_dst_port,uint32 gport,uint32 nexthop_ptr)
{
    uint8  gchip = 0;
    int32  ret = 0;
    uint8 xgpon_en = 0;
    uint16 lport = 0;
    uint16 value_tmp = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_logic_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }
    sys_usw_global_get_xgpon_en(lchip, &xgpon_en);
    if((p_usw_queue_master[lchip]->service_queue_mode != 2 && xgpon_en != 1) || (0 == p_usw_queue_master[lchip]->service_queue_mode))
    {
        return CTC_E_NOT_SUPPORT;
    }

    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));

    CTC_MIN_VALUE_CHECK(service_id, 1);
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);
    /* look up ingress service id is not exit*/
    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lchip = lchip;
    service_que_node.lport = lport;
    service_que_node.dir = CTC_INGRESS;

    p_service_que_logic_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if (NULL != p_service_que_logic_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry already exist \n");
        return CTC_E_EXIST;
    }

    /* look up egress service id */
    service_que_node.dir = CTC_EGRESS;
    p_service_que_logic_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    /*update of logic_dst_port and service id (service id and dest port has bind)*/
    if (NULL != p_service_que_logic_node && p_service_que_logic_node->group_is_alloc)
    {
        if(p_service_que_logic_node->logic_dst_port != logic_dst_port &&p_service_que_logic_node->logic_dst_port != 0)
        {
            return CTC_E_INVALID_PARAM;
        }
        if(p_service_que_logic_node->logic_dst_port == logic_dst_port)
        {
            return CTC_E_NONE;
        }
        value_tmp = nexthop_ptr ? 0 : CTC_QOS_SERVICE_FLAG_QID_EN;
        CTC_ERROR_RETURN(_sys_usw_qos_bind_service_dstport(lchip, service_id, gport, logic_dst_port,CTC_EGRESS,nexthop_ptr,0,0,value_tmp));
        return CTC_E_NONE;
    }
    /*update of logic_dst_port and service id (service id and dest port has not bind)*/
    else if(NULL != p_service_que_logic_node && p_service_que_logic_node->group_is_alloc == 0)
    {
        p_service_que_logic_node->logic_dst_port = logic_dst_port;
        p_service_que_logic_node->nexthop_ptr = nexthop_ptr;
        return CTC_E_NONE;
    }

    /*bind of logic_dst_port and service id*/
    p_service_que_logic_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
    if (NULL == p_service_que_logic_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_service_que_logic_node, 0, sizeof(sys_extend_que_node_t));

    p_service_que_logic_node->service_id = service_id;
    p_service_que_logic_node->lchip = lchip;
    p_service_que_logic_node->type = SYS_EXTEND_QUE_TYPE_SERVICE;
    p_service_que_logic_node->lport = lport;
    p_service_que_logic_node->logic_dst_port = logic_dst_port;
    p_service_que_logic_node->nexthop_ptr = nexthop_ptr;
    p_service_que_logic_node->dir = CTC_EGRESS;
    CTC_ERROR_GOTO(sys_usw_port_extender_add(lchip, p_service_que_logic_node), ret, error0);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);

    return CTC_E_NONE;

error0:
    mem_free(p_service_que_logic_node);

    return ret;
}

int32
_sys_usw_qos_unbind_service_logic_dstport(uint8 lchip, uint16 service_id, uint16 logic_dst_port, uint32 gport)
{
    uint8  gchip = 0;
    uint8 xgpon_en = 0;
    uint16 lport = 0;
    uint32 cmd = 0;
    sys_extend_que_node_t service_que_node;
    sys_extend_que_node_t* p_service_que_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }
    sys_usw_global_get_xgpon_en(lchip, &xgpon_en);
    if((p_usw_queue_master[lchip]->service_queue_mode != 2 && xgpon_en != 1) || (0 == p_usw_queue_master[lchip]->service_queue_mode))
    {
        return CTC_E_NOT_SUPPORT;
    }

    sal_memset(&service_que_node, 0, sizeof(sys_extend_que_node_t));
    CTC_MIN_VALUE_CHECK(service_id, 1);
    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(gport, lchip, lport);

    service_que_node.type = SYS_EXTEND_QUE_TYPE_SERVICE;
    service_que_node.service_id = service_id;
    service_que_node.lport = lport;
    service_que_node.lchip = lchip;
    service_que_node.dir = CTC_EGRESS;
    p_service_que_node = sys_usw_port_extender_lookup(lchip, &service_que_node);
    if (NULL == p_service_que_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    if(p_service_que_node->group_is_alloc)
    {
        if (MCHIP_QOS(lchip)->qos_queue_del_hash_key)
        {
            MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_service_que_node->key_index);
        }
        else
        {
            _sys_usw_queue_free_key_index(lchip, 1, p_service_que_node->key_index);
            cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
            DRV_IOCTL(lchip, p_service_que_node->key_index, cmd, &cmd);
        }
        p_service_que_node->logic_dst_port = 0;
    }
    else
    {
        sys_usw_port_extender_remove(lchip, p_service_que_node);
        mem_free(p_service_que_node);
    }
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
    return CTC_E_NONE;
}

int32
_sys_usw_qos_bind_service_logic_srcport(uint8 lchip, uint16 service_id, uint16 logic_port)
{
    uint8 update_flag = 0;
    uint16 old_serviceid = 0;
    uint16 dest_port = 0;
    int32 ret = 0;
    uint8 gchip = 0;
    ctc_slistnode_t *node, *node2, *next_node;
    sys_service_node_t* p_service = NULL;
    sys_service_node_t service;
    sys_qos_logicport_t* p_logic_port_node = NULL;
    sys_qos_logicport_service_t logicport_que_node;
    sys_qos_logicport_service_t* p_logicport_que_node = NULL;
    sys_qos_destport_t* p_dest_port_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }
    /*1.Service Queue based on Sevice ID retun none*/
    if(p_usw_queue_master[lchip]->service_queue_mode != 0)
    {
        return CTC_E_NONE;
    }
    if(logic_port == 0 || service_id == 0)
    {
        return CTC_E_INVALID_PARAM;
    }
    sal_memset(&logicport_que_node, 0, sizeof(sys_qos_logicport_service_t));
    logicport_que_node.logic_src_port = logic_port;
    sys_usw_get_gchip_id(lchip, &gchip);
    /*2.lookup by logic_port*/
    p_logicport_que_node = sys_usw_logicport_service_lookup(lchip, &logicport_que_node);
    if(p_logicport_que_node != NULL)
    {
        if(p_logicport_que_node->service_id == service_id)
        {
            return CTC_E_NONE;
        }
        old_serviceid = p_logicport_que_node->service_id;
        p_logicport_que_node->service_id = service_id;
        update_flag = 1;
    }
    else
    {
        p_logicport_que_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_logicport_service_t));
        if (NULL == p_logicport_que_node)
        {
            return CTC_E_NO_MEMORY;
        }
        p_logicport_que_node->logic_src_port = logic_port;
        p_logicport_que_node->service_id = service_id;
        sys_usw_logicport_service_add(lchip, p_logicport_que_node);
    }

    sal_memset(&service, 0, sizeof(service));
    service.service_id = service_id;
    p_service = sys_usw_service_lookup(lchip, &service);
    if (NULL == p_service)
    {
        ret = CTC_E_NONE;
        goto error1;
    }

    /*bind new logic port */
    p_logic_port_node = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_logicport_t));
    if (NULL == p_logic_port_node)
    {
        ret = CTC_E_NO_MEMORY;
        goto error1;
    }
    p_logic_port_node->logic_port = logic_port;
    ctc_slist_add_tail(p_service->p_logic_port_list, &p_logic_port_node->head);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT, 1);

    CTC_SLIST_LOOP(p_service->p_dest_port_list, node)
    {
        p_dest_port_node = _ctc_container_of(node, sys_qos_destport_t, head);
        dest_port = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip,p_dest_port_node->lport);
        CTC_ERROR_GOTO(_sys_usw_qos_bind_service_dstport(lchip, service_id,  dest_port, logic_port,CTC_INGRESS,0,0,0,0),ret,error2);

    }
    if(!update_flag )
    {
        return CTC_E_NONE;
    }
    service.service_id = old_serviceid;
    p_service = sys_usw_service_lookup(lchip, &service);
    if (NULL == p_service)
    {
       return CTC_E_NONE;
    }
    CTC_SLIST_LOOP_DEL(p_service->p_logic_port_list, node,next_node)
    {
        p_logic_port_node = _ctc_container_of(node, sys_qos_logicport_t, head);
        if (p_logic_port_node->logic_port != logic_port)
        {
            continue;
        }
        CTC_SLIST_LOOP(p_service->p_dest_port_list, node2)
        {
            p_dest_port_node = _ctc_container_of(node2, sys_qos_destport_t, head);
            dest_port = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip,p_dest_port_node->lport);
            _sys_usw_qos_unbind_service_dstport(lchip, old_serviceid, dest_port, logic_port,CTC_INGRESS,0,0);
        }
        ctc_slist_delete_node(p_service->p_logic_port_list, &p_logic_port_node->head);
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT, 1);
        mem_free(p_logic_port_node);
        break;
    }

    return CTC_E_NONE;
error2:
    CTC_SLIST_LOOP(p_service->p_dest_port_list, node)
    {
        p_dest_port_node = _ctc_container_of(node, sys_qos_destport_t, head);
        dest_port = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip,p_dest_port_node->lport);
        _sys_usw_qos_unbind_service_dstport(lchip, service_id,  dest_port, logic_port,CTC_INGRESS,0,0);
    }
    ctc_slist_delete_node(p_service->p_logic_port_list, &p_logic_port_node->head);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT, 1);
    mem_free(p_logic_port_node);

error1:
    if(update_flag == 0)
    {
        logicport_que_node.logic_src_port = logic_port;
        p_logicport_que_node = sys_usw_logicport_service_lookup(lchip, &logicport_que_node);
        if (NULL == p_logicport_que_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
            return CTC_E_NOT_EXIST;
        }
        sys_usw_logicport_service_remove(lchip, p_logicport_que_node);
        mem_free(p_logicport_que_node);
    }
    else
    {
        p_logicport_que_node->service_id = old_serviceid;
    }
    return ret;
}

int32
_sys_usw_qos_unbind_service_logic_srcport(uint8 lchip, uint16 service_id, uint16 logic_port)
{
    uint8 gchip = 0;
    uint16 dest_port = 0;
    sys_service_node_t* p_service = NULL;
    sys_service_node_t service;
    sys_qos_logicport_t* p_logic_port_node = NULL;
    sys_qos_destport_t* p_dest_port_node = NULL;
    ctc_slistnode_t* ctc_slistnode = NULL;
    sys_qos_logicport_service_t logicport_que_node;
    sys_qos_logicport_service_t* p_logicport_que_node = NULL;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NOT_SUPPORT;
    }
    if(p_usw_queue_master[lchip]->service_queue_mode != 0)
    {
        return CTC_E_NONE;
    }
    sal_memset(&service, 0, sizeof(service));
    service.service_id = service_id;
    p_service = sys_usw_service_lookup(lchip, &service);
    if (NULL == p_service)
    {
        return CTC_E_NONE;
    }
    if(logic_port == 0 || service_id == 0)
    {
        return CTC_E_INVALID_PARAM;
    }
    sal_memset(&logicport_que_node, 0, sizeof(sys_qos_logicport_service_t));
    logicport_que_node.logic_src_port = logic_port;
    /*2.lookup by logic_port*/
    p_logicport_que_node = sys_usw_logicport_service_lookup(lchip, &logicport_que_node);
    if(p_logicport_que_node != NULL && p_logicport_que_node->service_id == service_id)
    {
        sys_usw_logicport_service_remove(lchip, p_logicport_que_node);
        mem_free(p_logicport_que_node);
    }
    else
    {
        return CTC_E_NOT_EXIST;
    }
    CTC_SLIST_LOOP(p_service->p_logic_port_list, ctc_slistnode)
    {
        p_logic_port_node = _ctc_container_of(ctc_slistnode, sys_qos_logicport_t, head);
        if (p_logic_port_node->logic_port == logic_port)
        {
            break;
        }
    }
    sys_usw_get_gchip_id(lchip, &gchip);
    /*unbind logic port */
    CTC_SLIST_LOOP(p_service->p_dest_port_list, ctc_slistnode)
    {
        p_dest_port_node = _ctc_container_of(ctc_slistnode, sys_qos_destport_t, head);
        dest_port = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip,p_dest_port_node->lport);
        _sys_usw_qos_unbind_service_dstport(lchip,service_id,dest_port,logic_port,CTC_INGRESS,0,0);
    }

    ctc_slist_delete_node(p_service->p_logic_port_list, &p_logic_port_node->head);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT, 1);
    mem_free(p_logic_port_node);

    return CTC_E_NONE;
}


STATIC int32
_sys_usw_qos_create_port_extender_queue(uint8 lchip, uint16 lport, uint8 channel, uint16* grp_id, uint8 type)
{
    int32  ret = 0;
    uint32 group_id = 0;
    uint32 key_index = 0;
    uint32 cmd = 0;
    uint32 dest_map = 0;
    uint8  gchip = 0;
    sys_extend_que_node_t port_extender_node;
    sys_extend_que_node_t* p_port_extender_node = NULL;
    DsQueueMapTcamData_m  QueueMapTcamData;
    DsQueueMapTcamKey_m   QueueMapTcamKey;
    DsQueueMapTcamKey_m   QueueMapTcamMask;
    tbl_entry_t   tcam_key;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&QueueMapTcamData, 0 , sizeof(QueueMapTcamData));
    sal_memset(&QueueMapTcamKey, 0 , sizeof(QueueMapTcamKey));
    sal_memset(&QueueMapTcamMask, 0 , sizeof(QueueMapTcamMask));
    sal_memset(&port_extender_node, 0, sizeof(port_extender_node));

    port_extender_node.channel = type ? 0 : channel;
    port_extender_node.type = type ? SYS_EXTEND_QUE_TYPE_MCAST : SYS_EXTEND_QUE_TYPE_BPE;
    port_extender_node.lchip = lchip;
    port_extender_node.lport = lport;
    p_port_extender_node = sys_usw_port_extender_lookup(lchip, &port_extender_node);
    if (NULL != p_port_extender_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry already exist \n");
        return CTC_E_EXIST;
    }

    p_port_extender_node =  mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
    if (NULL == p_port_extender_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        return CTC_E_NO_MEMORY;
    }

    sal_memset(p_port_extender_node, 0, sizeof(sys_extend_que_node_t));

    ret = _sys_usw_queue_alloc_ext_group(lchip, 1, 1, &group_id);
    if (ret < 0)
    {
        mem_free(p_port_extender_node);
        return ret;
    }


    sys_usw_get_gchip_id(lchip, &gchip);
    dest_map = lport&0x1FF;
    dest_map = type ? (dest_map | 0x40000) : dest_map;

    if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_write_hash_key)
    {
        uint8 ext_type = 0;
        uint32 field_val = 0;

        field_val = SYS_ERM_PROFILE_DESTMAP_ENQ;
        cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
        CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val), ret, error0);

        ext_type = SYS_EXTEND_QUE_TYPE_BPE;
        CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_queue_write_hash_key(lchip, dest_map, channel, group_id, ext_type, 0, &key_index), ret, error0);
    }
    else
    {
        CTC_ERROR_GOTO(_sys_usw_qos_add_update_group_id_to_channel(lchip, group_id, channel, 1), ret, error0);
        CTC_ERROR_GOTO(_sys_usw_queue_alloc_key_index(lchip, 1, &key_index), ret, error0);

        /*write tcam ad*/
        SetDsQueueMapTcamData(V, extGroupId_f, &QueueMapTcamData, group_id);
        cmd = DRV_IOW(DsQueueMapTcamData_t, DRV_ENTRY_FLAG);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index, cmd, &QueueMapTcamData), ret, error1);

        /*write tcam key*/
        if (type == 0)
        {
            SetDsQueueMapTcamKey(V, channelId_f, &QueueMapTcamKey, channel);
            SetDsQueueMapTcamKey(V, channelId_f, &QueueMapTcamMask, 0x3f);
        }
        else
        {
            SetDsQueueMapTcamKey(V, macKnown_f, &QueueMapTcamKey, 0);
            SetDsQueueMapTcamKey(V, macKnown_f, &QueueMapTcamMask, 1);
        }
        SetDsQueueMapTcamKey(V, mcastIdValid_f, &QueueMapTcamKey, 0);
        SetDsQueueMapTcamKey(V, mcastIdValid_f, &QueueMapTcamMask, 1);
        SetDsQueueMapTcamKey(V, destChipIdMatch_f, &QueueMapTcamKey, 1);
        SetDsQueueMapTcamKey(V, destChipIdMatch_f, &QueueMapTcamMask, 1);
        SetDsQueueMapTcamKey(V, destMap_f, &QueueMapTcamKey, dest_map);
        SetDsQueueMapTcamKey(V, destMap_f, &QueueMapTcamMask, type ? 0x401ff : 0x1ff);
        cmd = DRV_IOW(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        tcam_key.data_entry = (uint32*)(&QueueMapTcamKey);
        tcam_key.mask_entry = (uint32*)(&QueueMapTcamMask);
        CTC_ERROR_GOTO(DRV_IOCTL(lchip, key_index, cmd, &tcam_key), ret, error1);
    }
    p_port_extender_node->lchip = lchip;
    p_port_extender_node->lport = lport;
    p_port_extender_node->type = type ? SYS_EXTEND_QUE_TYPE_MCAST : SYS_EXTEND_QUE_TYPE_BPE;
    p_port_extender_node->channel = type ? 0 : channel;
    p_port_extender_node->group_id = group_id;
    p_port_extender_node->key_index = key_index;
    CTC_ERROR_GOTO(sys_usw_port_extender_add(lchip, p_port_extender_node), ret, error2);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);
    *grp_id = p_port_extender_node->group_id;

    return CTC_E_NONE;

error2:
    if (MCHIP_QOS(lchip)->qos_queue_del_hash_key)
    {
        MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, key_index);
    }
    else
    {
        cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, key_index, cmd, &cmd));
    }
error1:
    if(!DRV_FROM_TMM(lchip))
    {
        _sys_usw_queue_free_key_index(lchip, 1, key_index);
    }
error0:
    _sys_usw_queue_free_ext_group(lchip, 1, group_id);
    mem_free(p_port_extender_node);

    return ret;
}

STATIC int32
_sys_usw_qos_destroy_port_extender_queue(uint8 lchip, uint16 dest_port, uint8 channel, uint16* grp_id, uint8 type)
{
    sys_extend_que_node_t port_extender_node;
    sys_extend_que_node_t* p_port_extender_node = NULL;
    uint32 cmd = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&port_extender_node, 0, sizeof(port_extender_node));
    port_extender_node.channel = type ? 0 : channel;
    port_extender_node.type = type ? SYS_EXTEND_QUE_TYPE_MCAST : SYS_EXTEND_QUE_TYPE_BPE;
    port_extender_node.lchip = lchip;
    port_extender_node.lport = dest_port;
    p_port_extender_node = sys_usw_port_extender_lookup(lchip, &port_extender_node);
    if (NULL == p_port_extender_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    sys_usw_port_extender_remove(lchip, p_port_extender_node);
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER, 1);

    if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_queue_del_hash_key)
    {
        uint32 field_val = 0;
        uint16 i = 0;
        sys_extend_que_node_t extend_que_node;
        sys_extend_que_node_t* p_extend_que_node = NULL;
        sal_memset(&extend_que_node, 0, sizeof(sys_extend_que_node_t));

        for (i = 0; i < MCHIP_CAP(SYS_CAP_PORT_NUM); i++)
        {
            extend_que_node.lport = i;
            extend_que_node.type = SYS_EXTEND_QUE_TYPE_BPE;
            extend_que_node.lchip = lchip;
            extend_que_node.channel = channel;
            p_extend_que_node = sys_usw_port_extender_lookup(lchip, &extend_que_node);
            if (NULL != p_extend_que_node)
            {
                break;
            }
        }
        if (i == MCHIP_CAP(SYS_CAP_PORT_NUM))
        {
            cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));
        }
        MCHIP_QOS(lchip)->qos_queue_del_hash_key(lchip, p_port_extender_node->key_index);
    }
    else
    {
        cmd = DRV_IOD(DsQueueMapTcamKey_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, p_port_extender_node->key_index, cmd, &cmd));

        CTC_ERROR_RETURN(_sys_usw_queue_free_key_index(lchip, 1, p_port_extender_node->key_index));
    }

    CTC_ERROR_RETURN(_sys_usw_queue_free_ext_group(lchip, 1, p_port_extender_node->group_id));

    *grp_id = p_port_extender_node->group_id;

    mem_free(p_port_extender_node);

    return CTC_E_NONE;
}

int32
_sys_usw_qos_add_update_group_id_to_channel(uint8 lchip, uint16 group_id, uint8 channel, uint8 flag)
{
    DsQMgrGrpChanMap_m grp_chan_map;
    uint32 cmd = 0;
    sys_queue_group_node_t *p_sys_group_node = NULL;

    if (DRV_FROM_TMM(lchip))
    {
        return CTC_E_NONE;
    }

    sal_memset(&grp_chan_map, 0, sizeof(DsQMgrGrpChanMap_m));
    cmd = DRV_IOR(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, group_id, cmd, &grp_chan_map));
    SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE, 1);
    SetDsQMgrGrpChanMap(V, channelId_f, &grp_chan_map, channel);
    cmd = DRV_IOW(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, group_id, cmd, &grp_chan_map));

    p_sys_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
    if (NULL == p_sys_group_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
        return CTC_E_NOT_EXIST;
    }
    p_sys_group_node->chan_id = flag ? channel : 0xff;  /*0~63*/

    return CTC_E_NONE;
}
/**
 @brief Mapping a extend port to channel.
*/
int32
_sys_usw_qos_add_extend_port_to_channel(uint8 lchip, uint16 lport, uint32 gport)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint16 group_id = 0;
    uint32 channel = 0;
    uint8 offset = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NONE;
    }

    /* enq_mode == 1 not support bpe*/
    if (p_usw_queue_master[lchip]->queue_num_per_extend_port == 0 || (p_usw_queue_master[lchip]->queue_num_per_extend_port != 0 &&
        p_usw_queue_master[lchip]->enq_mode == 1 && DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NONE;
    }
    /* notice gport is physical port can't get channel by SYS_GET_CHANNEL_ID api */
    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PHY_PORT_CHAN_ID, (void*)&channel));
    CTC_ERROR_RETURN(_sys_usw_qos_create_port_extender_queue(lchip, lport, channel, &group_id,0));
    if (MCHIP_QOS(lchip)->qos_sch_set_hsched)
    {
        CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, gport, group_id, 1, SYS_EXTEND_QUE_TYPE_BPE));
    }

    if(p_usw_queue_master[lchip]->oobfc_group_info.mode == CTC_QOS_OOBFC_MODE_TX_INGRESS
        || p_usw_queue_master[lchip]->oobfc_group_info.mode == CTC_QOS_OOBFC_MODE_TX_EGRESS)
    {
        OobFcCfgNum_m cfg_num;
        if(p_usw_queue_master[lchip]->oobfc_group_info.mode == CTC_QOS_OOBFC_MODE_TX_EGRESS || DRV_FROM_TMM(lchip))
        {
            offset = p_usw_queue_master[lchip]->oobfc_group_info.group_num;
        }
        else
        {
            offset = lport - CTC_MAP_GPORT_TO_LPORT(p_usw_queue_master[lchip]->oobfc_group_info.port_base);
        }
        CTC_ERROR_RETURN(_sys_usw_qos_bind_service_dstport_oobfc(lchip, offset, group_id));

        field_val = 1;
        cmd = DRV_IOW(DsIrmChannel_t, DsIrmChannel_localPhyPortResrcEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));

        cmd = DRV_IOR(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
        SetOobFcCfgNum(V, cfgChanNum_f, &cfg_num, p_usw_queue_master[lchip]->oobfc_group_info.group_num - 1);
        cmd = DRV_IOW(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_qos_remove_extend_port_to_channel(uint8 lchip, uint16 lport, uint32 gport)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint16 group_id = 0;
    uint32 channel = 0;
    uint8 offset = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    if(!MCHIP_SUB_FEATURE_CAP(lchip, SYS_FEATURE_QOS_HQOS))
    {
        return CTC_E_NONE;
    }

    /* enq_mode == 1 not support bpe*/
    if (p_usw_queue_master[lchip]->queue_num_per_extend_port == 0 || (p_usw_queue_master[lchip]->queue_num_per_extend_port != 0 &&
        p_usw_queue_master[lchip]->enq_mode == 1 && DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NONE;
    }
    /* notice gport is physical port can't get channel by SYS_GET_CHANNEL_ID api */
    dmps_port_info.gport = gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PHY_PORT_CHAN_ID, (void*)&channel));
    CTC_ERROR_RETURN(_sys_usw_qos_destroy_port_extender_queue(lchip, lport, channel, &group_id,0));
    if(!DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_RETURN(_sys_usw_qos_add_update_group_id_to_channel(lchip, group_id, 0, 0));
        CTC_ERROR_RETURN(_sys_usw_qos_flush_queue(lchip, channel, group_id, 0, 0));
    }
    else if (MCHIP_QOS(lchip)->qos_sch_set_hsched)
    {
        CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, gport, group_id, 0, SYS_EXTEND_QUE_TYPE_BPE));
    }

    if(p_usw_queue_master[lchip]->oobfc_group_info.mode == CTC_QOS_OOBFC_MODE_TX_INGRESS
        || p_usw_queue_master[lchip]->oobfc_group_info.mode == CTC_QOS_OOBFC_MODE_TX_EGRESS)
    {
        OobFcCfgNum_m cfg_num;
        if(p_usw_queue_master[lchip]->oobfc_group_info.mode == CTC_QOS_OOBFC_MODE_TX_EGRESS || DRV_FROM_TMM(lchip))
        {
            offset = p_usw_queue_master[lchip]->oobfc_group_info.group_num;
        }
        else
        {
            offset = lport - CTC_MAP_GPORT_TO_LPORT(p_usw_queue_master[lchip]->oobfc_group_info.port_base);
        }
        CTC_ERROR_RETURN(_sys_usw_qos_unbind_service_dstport_oobfc(lchip, offset, group_id));

        field_val = 0;
        cmd = DRV_IOW(DsIrmChannel_t, DsIrmChannel_localPhyPortResrcEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));

        cmd = DRV_IOR(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
        SetOobFcCfgNum(V, cfgChanNum_f, &cfg_num, p_usw_queue_master[lchip]->oobfc_group_info.group_num - 1);
        cmd = DRV_IOW(OobFcCfgNum_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &cfg_num));
    }
    return CTC_E_NONE;
}

int32
_sys_usw_qos_add_mcast_queue_to_channel(uint8 lchip, uint16 lport, uint8 channel, uint8 flag)
{
    uint16 group_id = 0;
    uint16 offset = 0;
    uint32 field_val = flag ? 3 : 0;/*flag is set indicate pri high*/
    uint32 field_id = 0;
    uint32 cmd = 0;

    if(p_usw_queue_master[lchip]->enq_mode != 1)
    {
        return CTC_E_NONE;
    }

    CTC_ERROR_RETURN(_sys_usw_qos_create_port_extender_queue(lchip, lport, channel, &group_id, 1));
    for(offset = 0; offset < 4; offset++)
    {
        field_id = DsQMgrExtSchMap_grpNode_0_chanNodeSel_f + offset;
        cmd = DRV_IOW(DsQMgrExtSchMap_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_remove_mcast_queue_to_channel(uint8 lchip, uint16 lport, uint8 channel)
{
    uint16 group_id = 0;
    uint16 offset = 0;
    uint32 field_val = 2;
    uint32 field_id = 0;
    uint32 cmd = 0;

    if(p_usw_queue_master[lchip]->enq_mode != 1)
    {
        return CTC_E_NONE;
    }
    CTC_ERROR_RETURN(_sys_usw_qos_destroy_port_extender_queue(lchip, lport, channel, &group_id,1));
    CTC_ERROR_RETURN(_sys_usw_qos_add_update_group_id_to_channel(lchip, group_id, 0, 0));
    for(offset = 0; offset < 4; offset++)
    {
        field_id = DsQMgrExtSchMap_grpNode_0_chanNodeSel_f + offset;
        cmd = DRV_IOW(DsQMgrExtSchMap_t, field_id);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, group_id, cmd, &field_val));
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_set_mc_queue_high_priority_en(uint8 lchip)
{

    if(DRV_FROM_TMM(lchip))
    {
        uint32 cmd = 0;
        QMgrCtl_m qmgr_ctl;
        cmd = DRV_IOR(QMgrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmgr_ctl));
        SetQMgrCtl(V, ctlQueAllHigh_f, &qmgr_ctl, 1);
        cmd = DRV_IOW(QMgrCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmgr_ctl));
    }
    else
    {
        uint8  gchip = 0;
        uint32  channel = 0;
        uint16 lport = 0;
#if (SDK_WORK_PLATFORM == 0) && (0 == SDK_WORK_ENV)
        uint32 port_type = 0;
        sys_usw_dmps_port_info_t dmps_port_info = {0};
#endif

        sys_usw_get_gchip_id(lchip, &gchip);
        for (lport = 0; lport < MCHIP_CAP(SYS_CAP_PORT_NUM); lport++)
        {
#if (SDK_WORK_PLATFORM == 0) && (0 == SDK_WORK_ENV)
            dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type));
            if(SYS_DMPS_RSV_PORT != port_type)
            {
                CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel));
                CTC_ERROR_RETURN(_sys_usw_qos_add_mcast_queue_to_channel(lchip, lport, channel, 1));
            }
#else
            if (lport < SYS_RSV_PORT_START)
            {
                channel = lport;
                CTC_ERROR_RETURN(_sys_usw_qos_add_mcast_queue_to_channel(lchip, lport, channel, 1));
            }
#endif
        }
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_check_pkt_adjust_profile(uint8 lchip, uint8 channel)
{
    uint32 field_val = 0;
    uint32 cmd = 0;
    uint8 profile_id = 0;
    uint8 index = 0;
    uint8 step1 = 0;
    uint8 step2 = 0;

    cmd = DRV_IOR(DsErmChannel_t, DsErmChannel_packetLengthAdjustProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));
    profile_id = field_val;
    for (index = 0; index < MCHIP_CAP(SYS_CAP_CHANID_MAX); index++)
    {
        cmd = DRV_IOR(DsErmChannel_t, DsErmChannel_packetLengthAdjustProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_val));
        if(field_val == profile_id && index != channel)
        {
            return CTC_E_NONE;
        }
    }

    step1 = QWritePktLenCtl_g1_1_packetLengthAdjust_f - QWritePktLenCtl_g1_0_packetLengthAdjust_f;
    step2 = QWritePktLenCtl_g1_1_packetLengthAdjustType_f - QWritePktLenCtl_g1_0_packetLengthAdjustType_f;

    field_val = 0;
    cmd = DRV_IOW(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjust_f + step1 * profile_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    cmd = DRV_IOW(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjustType_f + step2 * profile_id);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    return CTC_E_NONE;
}
int32
sys_usw_queue_set_queue_pkt_adjust(uint8 lchip, ctc_qos_queue_pkt_adjust_t* p_pkt)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 field_len = 0;
    uint32 field_type = 0;
    uint8 index = 0;
    uint8 new_index = 0xFF;
    uint8 old_index = 0;
    uint8 exist = 0;
    uint16 channel = 0;
    uint16 queue_id = 0;
    uint8 adjust_len = 0;
    uint8 adjust_type = 0;
    uint8 step1 = 0;
    uint8 step2 = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &p_pkt->queue, &queue_id));

    CTC_ERROR_RETURN(sys_usw_get_channel_by_queue_id(lchip, queue_id, &channel));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "channel id = %d\n", channel);

    adjust_len = (p_pkt->adjust_len) & 0x7F;
    adjust_type = (p_pkt->adjust_len) >> 7;
    adjust_type = adjust_len ? adjust_type : 0;
    if(adjust_len == 0 && adjust_type == 0 )
    {
        cmd = DRV_IOW(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjust_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        cmd = DRV_IOW(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjustType_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        CTC_ERROR_RETURN(_sys_usw_qos_check_pkt_adjust_profile(lchip, channel));

        cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_packetLengthAdjustProfId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));
        return CTC_E_NONE;
    }

    step1 = QWritePktLenCtl_g1_1_packetLengthAdjust_f - QWritePktLenCtl_g1_0_packetLengthAdjust_f;
    step2 = QWritePktLenCtl_g1_1_packetLengthAdjustType_f - QWritePktLenCtl_g1_0_packetLengthAdjustType_f;

    for (index = 0; index < 4; index++)
    {
        cmd = DRV_IOR(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjust_f + step1 * index);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_len));

        cmd = DRV_IOR(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjustType_f + step2 * index);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_type));

        if ((field_len == adjust_len) && (field_type == adjust_type))
        {
            new_index = index;
            exist = 1;
            break;
        }

        if (0 == field_len && index != 0)
        {
            new_index = index;
        }
    }

    if (new_index == 0xFF)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No resource in ASIC \n");
        return CTC_E_NO_RESOURCE;
    }

    cmd = DRV_IOR(DsErmChannel_t, DsErmChannel_packetLengthAdjustProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));
    old_index = field_val;

    if (new_index == old_index)
    {
        return CTC_E_NONE;
    }

    /*new index*/
    if (!exist)
    {
        CTC_ERROR_RETURN(_sys_usw_qos_check_pkt_adjust_profile(lchip, channel));
        field_val = adjust_len;
        cmd = DRV_IOW(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjust_f + step1 * new_index);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

        field_val = adjust_type;
        cmd = DRV_IOW(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjustType_f + step2 * new_index);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
    }

    field_val = new_index;
    cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_packetLengthAdjustProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "channel id = %d, NetPktAdjIndex:%d, value:%d\n", channel,  new_index, p_pkt->adjust_len);

    return CTC_E_NONE;
}

int32
sys_usw_queue_get_queue_pkt_adjust(uint8 lchip, ctc_qos_queue_pkt_adjust_t* p_pkt)
{
    uint32 cmd = 0;
    uint32 field_val = 0;
    uint32 field_len = 0;
    uint32 field_type = 0;
    uint16 channel = 0;
    uint16 queue_id = 0;
    uint8 step1 = 0;
    uint8 step2 = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &p_pkt->queue, &queue_id));
    CTC_ERROR_RETURN(sys_usw_get_channel_by_queue_id(lchip, queue_id, &channel));

    step1 = QWritePktLenCtl_g1_1_packetLengthAdjust_f - QWritePktLenCtl_g1_0_packetLengthAdjust_f;
    step2 = QWritePktLenCtl_g1_1_packetLengthAdjustType_f - QWritePktLenCtl_g1_0_packetLengthAdjustType_f;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "channel id = %d\n", channel);
    cmd = DRV_IOR(DsErmChannel_t, DsErmChannel_packetLengthAdjustProfId_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, channel, cmd, &field_val));
    cmd = DRV_IOR(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjust_f + step1 * field_val);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_len));
    cmd = DRV_IOR(QWritePktLenCtl_t, QWritePktLenCtl_g1_0_packetLengthAdjustType_f + step2 * field_val);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_type));
    p_pkt->adjust_len = field_type ? (field_len|0x80):field_len;

    return CTC_E_NONE;
}

int32
_sys_usw_qos_service_proc(uint8 lchip, ctc_qos_service_info_t *p_service_para)
{
    uint32 service_id = p_service_para->service_id;
    if(p_service_para->dir == CTC_EGRESS && (DRV_IS_DUET2(lchip)))
    {
        return CTC_E_NOT_SUPPORT;
    }
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch(p_service_para->opcode)
    {
    case CTC_QOS_SERVICE_ID_CREATE:
        CTC_ERROR_RETURN(
        _sys_usw_qos_create_service(lchip, service_id));
        break;

    case CTC_QOS_SERVICE_ID_DESTROY:
        CTC_ERROR_RETURN(
        _sys_usw_qos_destroy_service(lchip, service_id));
        break;

    case CTC_QOS_SERVICE_ID_BIND_DESTPORT:
        if(p_service_para->mode)
        {
            CTC_ERROR_RETURN(_sys_usw_qos_bind_service_dstport2(lchip, p_service_para));
        }
        else
        {
            CTC_ERROR_RETURN(
            _sys_usw_qos_bind_service_dstport(lchip, service_id, p_service_para->gport,0,p_service_para->dir,0,
                                            p_service_para->queue_id,p_service_para->oobfc_offset,p_service_para->flag));
        }

        break;

    case CTC_QOS_SERVICE_ID_UNBIND_DESTPORT:
        if(p_service_para->mode)
        {
            CTC_ERROR_RETURN(_sys_usw_qos_unbind_service_dstport2(lchip, p_service_para));
        }
        else
        {
            CTC_ERROR_RETURN(
            _sys_usw_qos_unbind_service_dstport(lchip, service_id, p_service_para->gport,0,p_service_para->dir,
                                            p_service_para->oobfc_offset, p_service_para->flag));
        }

        break;

    default:
        return CTC_E_INVALID_PARAM;
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_set_queue_reason_copp(uint8 lchip,uint16 reason_id,uint16 policer_ptr,uint8 is_glb_copp,uint8 enable)
{
    uint32 cmd = 0;
    uint8  idx,idx1,idx2;
    uint8  step = 0;
    uint16 exception = 0;
    uint8  excp_num = 0;
    uint16 excp_idx = 0;
    uint16 excp_array[32] = {0};
    EpeGlobalCoPPCfg_m gcoppCfg;
    EpeTxExcpCoPPCtl_m epe_copp_ctl;

    sal_memset(&gcoppCfg, 0, sizeof(EpeGlobalCoPPCfg_m));
    sal_memset(&epe_copp_ctl, 0, sizeof(EpeTxExcpCoPPCtl_m));

    /* get exception id*/
    CTC_ERROR_RETURN(sys_usw_queue_get_excp_idx_by_reason(lchip, reason_id,
                                                                excp_array,
                                                                &excp_num));
    for (idx = 0; idx < excp_num; idx++)
    {
        exception = excp_array[idx];

        excp_idx = SYS_REASON_GET_EXCP_INDEX(exception);

        if (is_glb_copp)
        {
            /* write to asic*/
            idx1 = excp_idx / 32;
            idx2 = excp_idx % 32;
            step = EpeGlobalCoPPCfg_g_1_coppPtr_f - EpeGlobalCoPPCfg_g_0_coppPtr_f;

            cmd = DRV_IOR(EpeGlobalCoPPCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &gcoppCfg));
            SetEpeGlobalCoPPCfg(V, g_0_coppValid_f + idx2 * step, &gcoppCfg, enable ? 1 : 0);
            SetEpeGlobalCoPPCfg(V, g_0_coppPtr_f + idx2 * step, &gcoppCfg, enable ? policer_ptr << 1 : 0);
            cmd = DRV_IOW(EpeGlobalCoPPCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, idx1, cmd, &gcoppCfg));

            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set global copp enable = %d, exception id = %d\n", enable, excp_idx);
        }
        else
        {
            /* EPE COPP support exception_subIndex 0~15 */
            CTC_VALUE_RANGE_CHECK(excp_idx, SYS_QOS_QUEUE_NORMAL_EXCP_TYPE_EPE_OTHER, SYS_QOS_QUEUE_NORMAL_EXCP_TYPE_EPE_OTHER + 15);

            excp_idx = excp_idx - SYS_QOS_QUEUE_NORMAL_EXCP_TYPE_EPE_OTHER;
            step = EpeTxExcpCoPPCtl_g_1_coppValid_f - EpeTxExcpCoPPCtl_g_0_coppValid_f;

            cmd = DRV_IOR(EpeTxExcpCoPPCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_copp_ctl));
            SetEpeTxExcpCoPPCtl(V, g_0_coppValid_f + excp_idx * step, &epe_copp_ctl, enable ? 1 : 0);
            SetEpeTxExcpCoPPCtl(V, g_0_coppPtr_f + excp_idx * step, &epe_copp_ctl, enable ? policer_ptr : 0);
            cmd = DRV_IOW(EpeTxExcpCoPPCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_copp_ctl));

            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Set epe copp enable = %d, exception id = %d\n", enable, excp_idx);
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_set_queue_reason_misc(uint8 lchip, ctc_qos_group_cpu_reason_misc_t* p_cpu_reason_misc_para)
{
    sys_qos_policer_param_t policer_param;
    uint8 is_glb_copp = 0;
    uint8 copp_en = 0;
    uint16 reason_id = 0;

    CTC_MAX_VALUE_CHECK(p_cpu_reason_misc_para->type, CTC_QOS_CPU_REASON_MAX -1);

    reason_id = p_cpu_reason_misc_para->cpu_reason;

    if(p_cpu_reason_misc_para->type == CTC_QOS_CPU_REASON_TRUNCATION)
    {
        if(DRV_IS_TMM(lchip) && (SYS_CHIP_SUB_VERSION_C != SYS_GET_CHIP_VERSION))
        {
            return CTC_E_NOT_SUPPORT;
        }
        CTC_ERROR_RETURN(sys_usw_cpu_reason_set_truncation(lchip, reason_id, p_cpu_reason_misc_para->truncated_len));
    }
    else
    {
        copp_en = p_cpu_reason_misc_para->policer_id == 0 ? 0 : 1;
        is_glb_copp = p_cpu_reason_misc_para->type == CTC_QOS_CPU_REASON_GLOBAL_COPP ? 1 : 0;
        policer_param.dir = CTC_EGRESS;
        policer_param.policer_ptr  = 0;
        policer_param.internal_use = 1;
        policer_param.glb_policer  = 1;
        policer_param.policer_id   = p_cpu_reason_misc_para->policer_id;
        policer_param.sys_policer_type = is_glb_copp ? SYS_QOS_POLICER_TYPE_FLOW : SYS_QOS_POLICER_TYPE_COPP;

        if(copp_en)
        {
            CTC_ERROR_RETURN(sys_usw_qos_policer_index_get(lchip, &policer_param));
            if ((policer_param.policer_ptr > 0x1FFF) || (policer_param.policer_ptr == 0))
            {
                return CTC_E_INVALID_PARAM;
            }
        }

        /* set copp*/
        CTC_ERROR_RETURN(_sys_usw_qos_set_queue_reason_copp(lchip, reason_id, policer_param.policer_ptr,
                                                    is_glb_copp, copp_en));

        p_usw_queue_master[lchip]->cpu_reason[reason_id].policer_id[is_glb_copp] = p_cpu_reason_misc_para->policer_id;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_CPU_REASON, 1);
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_get_queue_reason_misc(uint8 lchip, ctc_qos_group_cpu_reason_misc_t* p_cpu_reason_misc_para)
{
    CTC_PTR_VALID_CHECK(p_cpu_reason_misc_para);
    CTC_MAX_VALUE_CHECK(p_cpu_reason_misc_para->cpu_reason, CTC_PKT_CPU_REASON_MAX_COUNT - 1);
    CTC_MAX_VALUE_CHECK(p_cpu_reason_misc_para->type, CTC_QOS_CPU_REASON_MAX - 1);

    if(p_cpu_reason_misc_para->type == CTC_QOS_CPU_REASON_TRUNCATION)
    {
        if(DRV_IS_TMM(lchip) && (SYS_CHIP_SUB_VERSION_C != SYS_GET_CHIP_VERSION))
        {
            return CTC_E_NOT_SUPPORT;
        }
        CTC_ERROR_RETURN(sys_usw_cpu_reason_get_truncation(lchip, p_cpu_reason_misc_para->cpu_reason, &p_cpu_reason_misc_para->truncated_len));
    }
    else
    {
      p_cpu_reason_misc_para->policer_id = p_usw_queue_master[lchip]->cpu_reason[p_cpu_reason_misc_para->cpu_reason].policer_id[p_cpu_reason_misc_para->type];
    }
    return CTC_E_NONE;
}

/*before tmm, only flush basic queue group of network port, will discard pkt*/
int32
_sys_usw_queue_set_queue_flush(uint8 lchip, ctc_qos_queue_com_t* p_queue_flush)
{
    uint32 chan_id = 0;
    uint16 queue_id = 0;
    sys_qos_shape_profile_t shp_profile = {0};
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    if(p_queue_flush->queue.queue_type != CTC_QUEUE_TYPE_NETWORK_EGRESS)
    {
        return CTC_E_INVALID_PARAM;
    }

    if(CTC_IS_MCHAN_PORT(p_queue_flush->queue.gport))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Normal Gport with muti-channel not support queue flush \n");
        return CTC_E_NOT_SUPPORT;
    }

    dmps_port_info.gport = p_queue_flush->queue.gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
    if (SYS_COMMON_USELESS_CHANNEL == chan_id)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }

    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &p_queue_flush->queue, &queue_id));
    /*for restore shape profile*/
    if(!DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_RETURN(_sys_usw_queue_get_profile_from_hw(lchip, p_queue_flush->queue.gport, &shp_profile));
    }
    /*enqdrop*/
    CTC_ERROR_RETURN(_sys_usw_queue_set_port_drop_en(lchip, chan_id, TRUE, &shp_profile));

    _sys_usw_check_port_status(lchip,chan_id);

    CTC_ERROR_RETURN(_sys_usw_queue_set_port_drop_en(lchip, chan_id, FALSE, &shp_profile));
    return CTC_E_NONE;
}

int32
sys_usw_qos_queue_set(uint8 lchip, ctc_qos_queue_cfg_t* p_que_cfg, sys_cpu_reason_dest_info_t* p_dest_info)
{
    uint8 sub_queue_id = 0;
    uint8 sub_queue_id_min = 0;
    uint8 sub_queue_id_max = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    switch (p_que_cfg->type)
    {
    case CTC_QOS_QUEUE_CFG_PRI_MAP:
        CTC_ERROR_RETURN(
            sys_usw_set_priority_queue_map(lchip, &p_que_cfg->value.pri_map));
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_STATS_EN:
        if(DRV_FROM_TMM(lchip))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_queue_set_stats_enable(lchip, &p_que_cfg->value.stats));
        }
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_MAP:
        {

            ctc_qos_queue_cpu_reason_map_t* p_reason_map = &p_que_cfg->value.reason_map;

            sub_queue_id = p_reason_map->reason_group * MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM);
            if(p_reason_map->cpu_reason == CTC_PKT_CPU_REASON_C2C_PKT)
            {
                sub_queue_id_min = sub_queue_id;
                sub_queue_id_max = sub_queue_id + MCHIP_CAP(SYS_CAP_QOS_REASON_C2C_MAX_QUEUE_NUM) - 1;
            }
            else
            {
                sub_queue_id_min = (0xff == p_reason_map->queue_id) ? sub_queue_id : sub_queue_id + p_reason_map->queue_id;
                sub_queue_id_max = (0xff == p_reason_map->queue_id) ? (sub_queue_id_min + MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM) - 1) : sub_queue_id_min;
            }
            if(CTC_PKT_CPU_REASON_QUEUE_DROP_PKT == p_reason_map->cpu_reason)
            {
                uint16 reason = 0;
                uint16 sub_queue_id_tmp = 0;
                uint16 sub_queue_id_offset = 0;
                if (0xff == p_reason_map->queue_id || p_usw_queue_master[lchip]->monitor_drop_en)
                {
                    return CTC_E_INVALID_PARAM;
                }
                for (reason = 0; reason < CTC_PKT_CPU_REASON_MAX_COUNT; reason++)
                {
                    if(CTC_PKT_CPU_REASON_QUEUE_DROP_PKT == reason)
                    {
                        continue;
                    }
                    sub_queue_id_tmp = p_usw_queue_master[lchip]->cpu_reason[reason].sub_queue_id;
                    sub_queue_id_offset = CTC_IS_BIT_SET(sub_queue_id_tmp, SYS_REASON_PRI_ENQ_SHIFT) ? (MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM) - 1)
                        : (reason == CTC_PKT_CPU_REASON_C2C_PKT ? (MCHIP_CAP(SYS_CAP_QOS_REASON_C2C_MAX_QUEUE_NUM) - 1) : 0);
                    if(sub_queue_id_min >= (sub_queue_id_tmp&0xff) && sub_queue_id_min <= (sub_queue_id_tmp&0xff) + sub_queue_id_offset)
                    {
                        return CTC_E_INVALID_PARAM;
                    }
                }
            }
            else if((p_usw_queue_master[lchip]->monitor_drop_en == 1 || (0xff != p_usw_queue_master[lchip]->cpu_reason[CTC_PKT_CPU_REASON_QUEUE_DROP_PKT].sub_queue_id))
                && p_usw_queue_master[lchip]->cpu_reason[CTC_PKT_CPU_REASON_QUEUE_DROP_PKT].sub_queue_id >= sub_queue_id_min
                && p_usw_queue_master[lchip]->cpu_reason[CTC_PKT_CPU_REASON_QUEUE_DROP_PKT].sub_queue_id <= sub_queue_id_max
                && (0xff != p_reason_map->reason_group))
            {
                return CTC_E_INVALID_PARAM;
            }
            if (sub_queue_id >= p_usw_queue_master[lchip]->queue_num_for_cpu_reason && (0xff != p_reason_map->reason_group))
            { /*Exceed Max Cpu Reason Group*/
                return CTC_E_INVALID_PARAM;
            }
            CTC_ERROR_RETURN(sys_usw_cpu_reason_set_map(lchip,
                                                          p_reason_map->cpu_reason,
                                                          p_reason_map->queue_id,
                                                          p_reason_map->reason_group,
                                                          p_reason_map->acl_match_group,
                                                          p_dest_info));
        }
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_DEST:
        {
            ctc_qos_queue_cpu_reason_dest_t* p_reason_dest = &p_que_cfg->value.reason_dest;
            p_dest_info->dest_type = p_reason_dest->dest_type;
            if (CTC_PKT_CPU_REASON_TO_NHID == p_reason_dest->dest_type)
            {
                p_dest_info->dest_port = p_reason_dest->nhid;
                CTC_ERROR_RETURN(sys_usw_cpu_reason_set_dest(lchip, p_reason_dest->cpu_reason, p_dest_info));
            }
            else
            {
                p_dest_info->dest_port = p_reason_dest->dest_port;
                p_dest_info->raw_dest_en = p_reason_dest->raw_dest_en;
                p_dest_info->sub_idx = p_reason_dest->sub_index;
                CTC_ERROR_RETURN(sys_usw_cpu_reason_set_dest(lchip, p_reason_dest->cpu_reason, p_dest_info));
            }
        }
        break;
    case CTC_QOS_QUEUE_CFG_LENGTH_ADJUST:  /*GG will use nexthop adjust length index*/
        if (DRV_FROM_TMM(lchip))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_queue_set_queue_pkt_adjust(lchip, &p_que_cfg->value.pkt));
        }
        break;

    case CTC_QOS_QUEUE_CFG_SERVICE_BIND:
        if (DRV_FROM_AT(lchip))
        {
            return CTC_E_NOT_SUPPORT;
        }
        CTC_ERROR_RETURN(
        _sys_usw_qos_service_proc(lchip, &p_que_cfg->value.srv_queue_info));
        break;
    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_MISC:
        CTC_ERROR_RETURN(_sys_usw_qos_set_queue_reason_misc(lchip, &p_que_cfg->value.reason_misc));
        break;
    case CTC_QOS_QUEUE_CFG_FLUSH:
        CTC_ERROR_RETURN(_sys_usw_queue_set_queue_flush(lchip, &p_que_cfg->value.cfg));
        break;
    case CTC_QOS_QUEUE_CFG_QUEUE_NUM:
    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_MODE:
    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_PRIORITY:
    default:
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
        return CTC_E_NOT_SUPPORT;
    }

    return CTC_E_NONE;
}
int32
sys_usw_qos_queue_get(uint8 lchip, ctc_qos_queue_cfg_t* p_que_cfg)
{
    uint16 queue_id = 0;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);
    switch (p_que_cfg->type)
    {
    case CTC_QOS_QUEUE_CFG_PRI_MAP:
        CTC_ERROR_RETURN(sys_usw_get_priority_queue_map(lchip, &p_que_cfg->value.pri_map));
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_STATS_EN:
        if(DRV_FROM_TMM(lchip))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,  &p_que_cfg->value.stats.queue, &queue_id));
            CTC_ERROR_RETURN(_sys_usw_queue_get_stats_enable(lchip, queue_id, &p_que_cfg->value.stats.stats_en));
        }
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_MAP:
        {
            ctc_qos_queue_cpu_reason_map_t* p_reason_map = &p_que_cfg->value.reason_map;
            CTC_ERROR_RETURN(sys_usw_cpu_reason_get_map(lchip,p_reason_map->cpu_reason,&p_reason_map->queue_id,&p_reason_map->reason_group,&p_reason_map->acl_match_group));
        }
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_DEST:
        {
            uint16 excp_array[32] = {0};
            uint8  excp_num = 0;
            uint32 cmd         = 0;
            uint16  excp_idx = 0;
            uint8 excp_type = 0;
            uint8 idx = 0;
            EpeHdrAdjExcp_m epe_hdr_adj_excp;
            DsMetFifoExcp_m met_excp;
            ctc_qos_queue_cpu_reason_dest_t* p_reason_dest = &p_que_cfg->value.reason_dest;
            CTC_MAX_VALUE_CHECK(p_reason_dest->cpu_reason, CTC_PKT_CPU_REASON_MAX_COUNT - 1);
            p_reason_dest->dest_type = p_usw_queue_master[lchip]->cpu_reason[p_reason_dest->cpu_reason].dest_type;
            if (CTC_PKT_CPU_REASON_TO_NHID == p_reason_dest->dest_type)
            {
                p_reason_dest->nhid = p_usw_queue_master[lchip]->cpu_reason[p_reason_dest->cpu_reason].dest_port;
            }
            else
            {
                p_reason_dest->dest_port = p_usw_queue_master[lchip]->cpu_reason[p_reason_dest->cpu_reason].dest_port;
            }
            sys_usw_queue_get_excp_idx_by_reason(lchip, p_reason_dest->cpu_reason, excp_array, &excp_num);
            for (idx = 0; idx < excp_num; idx++)
            {
                excp_type = SYS_REASON_GET_EXCP_TYPE(excp_array[idx]);

                if (excp_type != SYS_QOS_QUEUE_NORMAL_EXCP)
                {
                    continue;
                }
                excp_idx = SYS_REASON_GET_EXCP_INDEX(excp_array[idx]);
                if (DRV_FROM_TMM(lchip))
                {
                    cmd = DRV_IOR(EpeHdrAdjExcp_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, excp_idx, cmd, &epe_hdr_adj_excp));
                    p_reason_dest->raw_dest_en = (GetEpeHdrAdjExcp(V, destMapKeepMode_f, &epe_hdr_adj_excp) == 2) ? 1:0;
                }
                else
                {
                    cmd = DRV_IOR(DsMetFifoExcp_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, excp_idx, cmd, &met_excp));
                    p_reason_dest->raw_dest_en = GetDsMetFifoExcp(V, keepPacketHeaderDestMap_f, &met_excp);
                }
            }
        }
        break;
    case CTC_QOS_QUEUE_CFG_LENGTH_ADJUST:
        if (DRV_FROM_TMM(lchip))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
            return CTC_E_NOT_SUPPORT;
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_queue_get_queue_pkt_adjust(lchip, &p_que_cfg->value.pkt));
        }
        break;
    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_MISC:
        CTC_ERROR_RETURN(_sys_usw_qos_get_queue_reason_misc(lchip, &p_que_cfg->value.reason_misc));
        break;
    default:
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Feature not supported \n");
        return CTC_E_NOT_SUPPORT;
    }
    return CTC_E_NONE;
}

int32
sys_usw_qos_alloc_monitor_drop_reason_queue_id(uint8 lchip, sys_cpu_reason_dest_info_t *p_dest_info)
{
    uint8  valid = 0;
    uint8  group_id = 0;
    uint8  queue_id = 0;
    uint16 reason = 0;
    uint16 sub_queue_id = 0;
    uint16 max_queue_num = p_usw_queue_master[lchip]->queue_num_for_cpu_reason;
    uint16 sub_queue_id_min = 0;
    uint16 sub_queue_id_max = 0;
    sub_queue_id = p_usw_queue_master[lchip]->cpu_reason[CTC_PKT_CPU_REASON_QUEUE_DROP_PKT].sub_queue_id ;
    if((sub_queue_id&0xFF) != 0xFF)
    {
        valid = 1;
    }
    else
    {
        sub_queue_id = 0;
    }
    for(; !valid &&(sub_queue_id < max_queue_num) ; sub_queue_id ++)
    {
        for(reason = CTC_PKT_CPU_REASON_DROP; reason < CTC_PKT_CPU_REASON_MAX_COUNT; reason++)
        {
            sub_queue_id_min = p_usw_queue_master[lchip]->cpu_reason[reason].sub_queue_id;
            sub_queue_id_max = (reason == CTC_PKT_CPU_REASON_C2C_PKT) ? (sub_queue_id_min + MCHIP_CAP(SYS_CAP_QOS_REASON_C2C_MAX_QUEUE_NUM) - 1)
                : (CTC_IS_BIT_SET(sub_queue_id_min, SYS_REASON_PRI_ENQ_SHIFT) ? (sub_queue_id_min + MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM) - 1) : sub_queue_id_min);
            if((sub_queue_id_min&0xFF) <= sub_queue_id && sub_queue_id <= (sub_queue_id_max&0xFF))
            {/*in-use*/
                break;
            }
        }
        if(reason == CTC_PKT_CPU_REASON_MAX_COUNT)
        {
            break;
        }
    }
    if(sub_queue_id == max_queue_num)
    {
        return CTC_E_INVALID_PARAM;
    }

    reason = CTC_PKT_CPU_REASON_QUEUE_DROP_PKT;
    group_id = sub_queue_id / MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM);
    queue_id = sub_queue_id % MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM);

    CTC_ERROR_RETURN(sys_usw_cpu_reason_set_map(lchip,  reason, queue_id, group_id, 0, p_dest_info));
    p_dest_info->sub_queue_id = sub_queue_id;

    return CTC_E_NONE;
}

int32
sys_usw_qos_free_monitor_drop_reason_queue_id(uint8 lchip)
{
    p_usw_queue_master[lchip]->cpu_reason[CTC_PKT_CPU_REASON_QUEUE_DROP_PKT].sub_queue_id = 0xFFFF;
    return CTC_E_NONE;
}


extern int32
sys_usw_qos_set_monitor_drop_queue_id(uint8 lchip,  ctc_qos_queue_drop_monitor_t* drop_monitor, sys_nh_info_dsnh_t* p_nhinfo)
{
    uint32 cmd = 0;
    ErmSpanOnDropCtl_m span_on_drop_ctl;
    uint16 lport = 0;
    uint32 src_chan_id = 0;
    uint32 dst_chan_id = 0;
    uint32 array_val[8] = {0};
    uint32 src_gport = 0;
    uint32 dst_gport = 0;
    uint8 is_cpu_port = 0;
    uint8 is_net_port = 0;
    uint16 sub_queue_id = 0;
    uint32 field_val = 0;
    uint32 field_id = 0;
    uint16 queue_index = 0;
    uint32 nexthop_ptr = 0;
    uint16 index = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    DsQMgrGrpChanMap_m grp_chan_map;
    BufRetrvSpanCtl_m buffer_retrieve_ctl;
    EpeHdrAdjSpanCtl_m hdradj_span_ctl;
    

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&span_on_drop_ctl, 0, sizeof(span_on_drop_ctl));
    sal_memset(&buffer_retrieve_ctl, 0, sizeof(buffer_retrieve_ctl));
    sal_memset(&grp_chan_map, 0, sizeof(grp_chan_map));
    sal_memset(&hdradj_span_ctl, 0, sizeof(EpeHdrAdjSpanCtl_m));

    src_gport = drop_monitor->src_gport;
    dst_gport = drop_monitor->nhid ? p_nhinfo->gport : drop_monitor->dst_gport;
    nexthop_ptr = p_nhinfo->dsnh_offset;
    if(src_gport == dst_gport)
    {
        return CTC_E_INVALID_PARAM;
    }
    if (CTC_IS_CPU_PORT(dst_gport))
    {
        is_cpu_port = 1;
        dst_chan_id = MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0);
    }
    else if(drop_monitor->nhid && p_nhinfo->nh_entry_type == SYS_NH_TYPE_ILOOP)
    {
        dst_chan_id = MCHIP_CAP(SYS_CAP_CHANID_ILOOP);
    }
    else if(drop_monitor->nhid && p_nhinfo->nh_entry_type == SYS_NH_TYPE_ELOOP)
    {
        dst_chan_id = MCHIP_CAP(SYS_CAP_CHANID_ELOOP);
    }
    else
    {
        if(p_usw_queue_master[lchip]->enq_mode == 1 && DRV_IS_DUET2(lchip))
        {
            return CTC_E_NOT_SUPPORT;
        }
        is_net_port = 1;
        dmps_port_info.gport = dst_gport;
        SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(dst_gport, lchip, lport);
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &dst_chan_id));
        if(!SYS_IS_NETWORK_CHANNEL(dst_chan_id))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
            return CTC_E_INVALID_PORT;
        }
    }

    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(src_gport, lchip, lport);
    dmps_port_info.gport = src_gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &src_chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(src_chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    cmd = DRV_IOR(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));

    if(GetErmSpanOnDropCtl(V, spanOnDropEn_f, &span_on_drop_ctl))
    {
        if(dst_chan_id != GetErmSpanOnDropCtl(V, spanOnDropChannelId_f, &span_on_drop_ctl))
        {
            return CTC_E_INVALID_PORT;
        }
    }

    if (drop_monitor->enable >= 1)
    {
        if(is_cpu_port == 1)
        {
            sub_queue_id = p_nhinfo->ecmp_group_id + MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP);/*temp reuse as sub queue id*/
            nexthop_ptr = CTC_PKT_CPU_REASON_QUEUE_DROP_PKT << 4;
            if(!DRV_FROM_TMM(lchip))
            {
                queue_index = sub_queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP);
                field_val = 0;
                field_id = DsQMgrDmaSchMap_chanNodeSel_f;
                cmd = DRV_IOW(DsQMgrDmaSchMap_t, field_id);
                CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_index, cmd, &field_val));
            }
        }
        else if(is_net_port == 1)
        {
            if(DRV_FROM_TMM(lchip))
            {
                cmd = DRV_IOR(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));
                GetErmSpanOnDropCtl(A, spanOnDropChannelEn_f, &span_on_drop_ctl, array_val);
                if (array_val[0] == 0 && array_val[1] == 0 && array_val[2] == 0 && array_val[3] == 0
                    && array_val[4] == 0 && array_val[5] == 0 && array_val[6] == 0 && array_val[7] == 0)
                {
                    if (MCHIP_QOS(lchip)->qos_sch_set_hsched)
                    {
                        CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, dst_gport,
                            MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM) - 1, drop_monitor->enable, SYS_EXTEND_QUE_TYPE_SERVICE));
                    }
                }
                sub_queue_id = MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) - 1;
            }
            else
            {
                cmd = DRV_IOR(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM) - 1, cmd, &grp_chan_map));
                SetDsQMgrGrpChanMap(V, channelId_f, &grp_chan_map, dst_chan_id);
                cmd = DRV_IOW(DsQMgrGrpChanMap_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM) - 1, cmd, &grp_chan_map));
                sub_queue_id = MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) - 1;
            }
        }
        else
        {
            /*
            Because of RTL limitation, span on drop packet can not coexist with normal packet on the same queue.
            Normal packet pass through the first 7 queues and span on drop packet pass through last queue.
            */
            field_val = DRV_FROM_TMM(lchip) ? SYS_ERM_PROFILE_MOD : 3;
            cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dst_chan_id, cmd, &field_val));

            sub_queue_id = dst_chan_id * MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN) + 7;
        }
        if(!DRV_FROM_TMM(lchip))
        {
            cmd = DRV_IOR(BufRetrvSpanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buffer_retrieve_ctl))
            SetBufRetrvSpanCtl(V, spanOnDropRsvQueId_f , &buffer_retrieve_ctl, sub_queue_id );
            SetBufRetrvSpanCtl(V, spanOnDropEn_f , &buffer_retrieve_ctl, 1);
            SetBufRetrvSpanCtl(V, spanOnDropNextHopPtr_f , &buffer_retrieve_ctl, nexthop_ptr);
            cmd = DRV_IOW(BufRetrvSpanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buffer_retrieve_ctl));
        }
        else
        {
            cmd = DRV_IOR(EpeHdrAdjSpanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hdradj_span_ctl))
            SetEpeHdrAdjSpanCtl(V, spanOnDropRsvQueId_f , &hdradj_span_ctl, sub_queue_id);
            SetEpeHdrAdjSpanCtl(V, spanOnDropNextHopPtr_f , &hdradj_span_ctl, nexthop_ptr);
            cmd = DRV_IOW(EpeHdrAdjSpanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hdradj_span_ctl));

            SetEpeHdrAdjSpanCtl(V, spanOnDropEn_f , &hdradj_span_ctl, 1);
            cmd = DRV_IOW(EpeHdrAdjSpanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hdradj_span_ctl));
        }

        p_usw_queue_master[lchip]->monitor_drop_en = 1;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);

        /*must set spanOnDropEnable first, bug109941*/
        if(!DRV_FROM_TMM(lchip))
        {
            field_val = 1;
            cmd = DRV_IOW(ErmMiscCtl_t, ErmMiscCtl_spanOnDropEnable_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        }

        cmd = DRV_IOR(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));

        /*must set dest channel and queue first, bug122952*/
        SetErmSpanOnDropCtl(V, spanOnDropEnable_f , &span_on_drop_ctl, 1);
        SetErmSpanOnDropCtl(V, spanOnDropQueueId_f , &span_on_drop_ctl, sub_queue_id);
        SetErmSpanOnDropCtl(V, spanOnDropChannelId_f , &span_on_drop_ctl, dst_chan_id);
        cmd = DRV_IOW(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));

        GetErmSpanOnDropCtl(A, spanOnDropChannelEn_f, &span_on_drop_ctl, array_val);
        CTC_BIT_SET(array_val[src_chan_id / 32], src_chan_id&0x1F);
        SetErmSpanOnDropCtl(V, spanOnDropEn_f , &span_on_drop_ctl, 1);
        SetErmSpanOnDropCtl(V, spanOnDropTrafficClass_f , &span_on_drop_ctl, drop_monitor->pri_class_bmp ? drop_monitor->pri_class_bmp : 0xFF);
        SetErmSpanOnDropCtl(A, spanOnDropChannelEn_f, &span_on_drop_ctl, array_val);
        cmd = DRV_IOW(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));

    }
    else
    {
        cmd = DRV_IOR(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));

        /*1.delete span src*/
        GetErmSpanOnDropCtl(A, spanOnDropChannelEn_f, &span_on_drop_ctl, array_val);
        CTC_BIT_UNSET(array_val[src_chan_id / 32], src_chan_id&0x1F);
        SetErmSpanOnDropCtl(A, spanOnDropChannelEn_f, &span_on_drop_ctl, array_val);
        cmd = DRV_IOW(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));
        if(array_val[0] != 0 || array_val[1] != 0 || array_val[2] != 0 || array_val[3] != 0
            || array_val[4] != 0 || array_val[5] != 0 || array_val[6] != 0 || array_val[7] != 0)
        {
            return CTC_E_NONE;
        }

        /*2.delete span dest ,if spanCnt is not 0 can not delete span dest*/
        cmd = DRV_IOR(DsErmMiscCnt_t, DsErmMiscCnt_spanCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        while (field_val)
        {
            sal_task_sleep(20);
            if ((index++) > 1000)
            {
                return CTC_E_INVALID_PARAM;
            }
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        }
        if(is_cpu_port)
        {
            sys_usw_qos_free_monitor_drop_reason_queue_id(lchip);
        }
        p_usw_queue_master[lchip]->monitor_drop_en = 0;
        SYS_USW_REGISTER_WB_SYNC_EN(lchip, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER, 1);
        if(!DRV_FROM_TMM(lchip))
        {
            if (is_cpu_port == 0)
            {
                if (is_net_port)
                {
                    cmd = DRV_IOW(DsQMgrGrpChanMap_t, DsQMgrGrpChanMap_channelId_f);
                    dst_chan_id = 0;
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM) - 1, cmd, &dst_chan_id));
                }
                else
                {
                    field_val = 0;
                    cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dst_chan_id, cmd, &field_val));
                }
            }

            cmd = DRV_IOR(BufRetrvSpanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buffer_retrieve_ctl))
            SetBufRetrvSpanCtl(V, spanOnDropEn_f , &buffer_retrieve_ctl, 0);
            cmd = DRV_IOW(BufRetrvSpanCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buffer_retrieve_ctl));
        }
        else
        {
            if(is_cpu_port == 0)
            {
                if (is_net_port == 1)
                {
                    if (MCHIP_QOS(lchip)->qos_sch_set_hsched)
                    {
                        CTC_ERROR_RETURN(MCHIP_QOS(lchip)->qos_sch_set_hsched(lchip, dst_gport,
                                         MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM) - 1, drop_monitor->enable, SYS_EXTEND_QUE_TYPE_SERVICE));
                    }
                }
                else
                {
                    field_val = 0;
                    cmd = DRV_IOW(DsErmChannel_t, DsErmChannel_ermProfId_f);
                    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, dst_chan_id, cmd, &field_val));
                }
            }
        }
        field_val = 0;
        cmd = DRV_IOW(ErmSpanOnDropCtl_t, ErmSpanOnDropCtl_spanOnDropEn_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        cmd = DRV_IOW(ErmSpanOnDropCtl_t, ErmSpanOnDropCtl_spanOnDropChannelId_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));
        cmd = DRV_IOW(ErmSpanOnDropCtl_t, ErmSpanOnDropCtl_spanOnDropEnable_f);/*TMM*/
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

        cmd = DRV_IOW(ErmMiscCtl_t, ErmMiscCtl_spanOnDropEnable_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

        cmd = DRV_IOR(EpeHdrAdjSpanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hdradj_span_ctl))
        SetEpeHdrAdjSpanCtl(V, spanOnDropEn_f , &hdradj_span_ctl, 0);
        SetEpeHdrAdjSpanCtl(V, spanOnDropRsvQueId_f , &hdradj_span_ctl, 0x3FFF);
        cmd = DRV_IOW(EpeHdrAdjSpanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &hdradj_span_ctl));
    }

    return CTC_E_NONE;
}

extern int32
sys_usw_qos_get_monitor_drop_queue_id(uint8 lchip,  ctc_qos_queue_drop_monitor_t* drop_monitor)
{
    uint32 array_val[8] = {0};
    uint32 cmd = 0;
    uint32 src_chan_id = 0;
    uint32 dst_chan_id = 0;
    uint32 src_gport = 0;
    uint16 lport = 0;
    uint8 gchip = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    ErmSpanOnDropCtl_m span_on_drop_ctl;

    sal_memset(&span_on_drop_ctl, 0, sizeof(span_on_drop_ctl));
    src_gport = drop_monitor->src_gport;
    SYS_MAP_CTC_GPORT_TO_DRV_LPORT_WITH_CHECK(src_gport, lchip, lport);

    dmps_port_info.gport = src_gport;
    CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &src_chan_id));
    if (!SYS_IS_NETWORK_CHANNEL(src_chan_id))
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    cmd = DRV_IOR(ErmSpanOnDropCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &span_on_drop_ctl));

    GetErmSpanOnDropCtl(A, spanOnDropChannelEn_f, &span_on_drop_ctl, array_val);
    drop_monitor->enable = CTC_IS_BIT_SET(array_val[src_chan_id / 32], src_chan_id&0x1F);
    if(drop_monitor->enable == 0)
    {
        return CTC_E_NONE;
    }
    dst_chan_id = GetErmSpanOnDropCtl(V, spanOnDropChannelId_f , &span_on_drop_ctl);
    if(dst_chan_id == MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0))
    {
        drop_monitor->dst_gport = 0x10000000;
    }
    else
    {
        if(p_usw_queue_master[lchip]->enq_mode == 1 && DRV_IS_DUET2(lchip))
        {
            return CTC_E_NOT_SUPPORT;
        }
        lport = SYS_GET_LPORT_ID_WITH_CHAN(lchip, 0, dst_chan_id);
        CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip));
        drop_monitor->dst_gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
    }

    drop_monitor->pri_class_bmp = GetErmSpanOnDropCtl(V, spanOnDropTrafficClass_f , &span_on_drop_ctl);
    return CTC_E_NONE;
}
/**
 @brief Get service queue statistics.
*/
int32
sys_usw_queue_stats_query(uint8 lchip, ctc_qos_queue_stats_t* p_stats_param)
{
    ctc_stats_basic_t stats;
    ctc_stats_basic_t stats2;
    sys_stats_param_t st_param;
    ctc_qos_queue_stats_info_t* p_stats = NULL;
    uint16 queue_id = 0;
    uint16 queue_base = 0;
    uint32 stats_ptr = 0;
    uint32 cmd = 0;
    uint32 chan_id = 0;
    uint8  loop = 0;
    uint8  stats_en = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&stats, 0, sizeof(stats));
    sal_memset(&stats2, 0, sizeof(stats2));
    sal_memset(&st_param, 0, sizeof(st_param));
    if(p_stats_param->queue.queue_type == CTC_QUEUE_TYPE_NETWORK_EGRESS && p_stats_param->queue.queue_id == 0xff && DRV_FROM_TM(lchip))
    {
        p_stats_param->queue.queue_id = 0;
        p_stats = &p_stats_param->stats;
    }
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip,
                                                       &p_stats_param->queue,
                                                       &queue_id));

    CTC_ERROR_RETURN(_sys_usw_queue_get_stats_enable(lchip, queue_id, &stats_en));
    if(!stats_en)
    {
        return CTC_E_NONE;
    }

    if (NULL != p_stats)
    {
        p_stats_param->queue.queue_id = 0xff;
        CTC_ERROR_RETURN(sys_usw_flow_stats_get_queue_stats2(lchip, p_stats_param->queue.gport, queue_id, p_stats));
        return CTC_E_NONE;
    }

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Queue id = %d\n", queue_id);

    p_stats = &p_stats_param->stats;
    st_param.type = SYS_STATS_TYPE_QUEUE;
    st_param.num = 1;

    if (!DRV_FROM_TMM(lchip))
    {
        if (DRV_IS_DUET2(lchip))
        {
            stats_ptr = queue_id << 1;
        }
        else
        {
            cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &stats_ptr));
        }
        if (!p_stats_param->stats_en || CTC_IS_BIT_SET(p_stats_param->stats_en, SYS_QUEUE_STATS_DROP_PKT_SHIFT))
        {
            st_param.ptr = stats_ptr + 1;
            CTC_ERROR_RETURN(sys_usw_flow_stats_get_stats(lchip, &st_param, &stats));
            p_stats->drop_packets = stats.packet_count;
            p_stats->drop_bytes   = stats.byte_count;
        }

        if (!p_stats_param->stats_en || CTC_IS_BIT_SET(p_stats_param->stats_en, SYS_QUEUE_STATS_DEQ_PKT_SHIFT))
        {
            st_param.ptr = stats_ptr;
            CTC_ERROR_RETURN(sys_usw_flow_stats_get_stats(lchip, &st_param, &stats));
            p_stats->deq_packets  = stats.packet_count;
            p_stats->deq_bytes    = stats.byte_count;
        }
    }
    else
    {
        dmps_port_info.gport = p_stats_param->queue.gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && SYS_IS_NETWORK_CHANNEL(chan_id)
            && p_usw_queue_master[lchip]->group_id_ets[chan_id].group_id != INVALID_QUEUE_GROUP_ID_ETS
            && p_stats_param->queue.queue_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP))
        {
            for (loop = 0; loop < SYS_SCHED_MAX_ETS_EXT_GRP_NUM; loop++)
            {
                SYS_TMM_QUE_ID_FR_GROUP(queue_base, (p_usw_queue_master[lchip]->group_id_ets[chan_id].group_id + loop), 1);
                st_param.ptr = queue_base + p_stats_param->queue.queue_id;
                CTC_ERROR_RETURN(sys_usw_flow_stats_get_stats(lchip, &st_param, &stats2));
                stats.packet_count += stats2.packet_count;
                stats.byte_count += stats2.byte_count;
            }
            SYS_TMM_QUE_ID_FR_GROUP(queue_base, SYS_GROUP_ID_BY_CHAN(chan_id), 1);
            st_param.ptr = queue_base + p_stats_param->queue.queue_id;
            CTC_ERROR_RETURN(sys_usw_flow_stats_get_stats(lchip, &st_param, &stats2));
            stats.packet_count += stats2.packet_count;
            stats.byte_count += stats2.byte_count;
        }
        else
        {
            st_param.ptr = queue_id;
            CTC_ERROR_RETURN(sys_usw_flow_stats_get_stats(lchip, &st_param, &stats));
        }

        if (!p_stats_param->stats_en || CTC_IS_BIT_SET(p_stats_param->stats_en, SYS_QUEUE_STATS_DROP_PKT_SHIFT))
        {
            p_stats->drop_packets = stats.packet_count;
        }
        if (!p_stats_param->stats_en || CTC_IS_BIT_SET(p_stats_param->stats_en, SYS_QUEUE_STATS_DEQ_PKT_SHIFT))
        {
            p_stats->deq_packets  = stats.byte_count;
        }
    }
    return CTC_E_NONE;
}

/**
 @brief Get service queue statistics.
*/
int32
sys_usw_queue_stats_clear(uint8 lchip, ctc_qos_queue_stats_t* p_stats_param)
{
    uint16 queue_id = 0;
    uint16 queue_base = 0;
    uint32 stats_ptr = 0;
    uint32 cmd = 0;
    uint32 chan_id = 0;
    uint8  loop = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    sys_stats_param_t st_param;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s()\n", __FUNCTION__);

    sal_memset(&st_param, 0, sizeof(st_param));
    CTC_ERROR_RETURN(sys_usw_queue_get_queue_id(lchip, &p_stats_param->queue,
                                                       &queue_id));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "Queue id = %d\n", queue_id);

    st_param.type = SYS_STATS_TYPE_QUEUE;
    st_param.num = 1;
    if (!DRV_FROM_TMM(lchip))
    {
        if (DRV_IS_DUET2(lchip))
        {
            stats_ptr = queue_id << 1;
        }
        else
        {
            cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &stats_ptr));
        }
        if (!p_stats_param->stats_en || CTC_IS_BIT_SET(p_stats_param->stats_en, SYS_QUEUE_STATS_DROP_PKT_SHIFT))
        {
            st_param.ptr = stats_ptr + 1;
            CTC_ERROR_RETURN(sys_usw_flow_stats_clear_stats(lchip, &st_param));
        }
        if (!p_stats_param->stats_en || CTC_IS_BIT_SET(p_stats_param->stats_en, SYS_QUEUE_STATS_DEQ_PKT_SHIFT))
        {
            st_param.ptr = stats_ptr;
            CTC_ERROR_RETURN(sys_usw_flow_stats_clear_stats(lchip, &st_param));
        }
    }
    else
    {
        dmps_port_info.gport = p_stats_param->queue.gport;
        CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id));
        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)) && SYS_IS_NETWORK_CHANNEL(chan_id)
            && p_usw_queue_master[lchip]->group_id_ets[chan_id].group_id != INVALID_QUEUE_GROUP_ID_ETS
            && p_stats_param->queue.queue_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP))
        {
            for (loop = 0; loop < SYS_SCHED_MAX_ETS_EXT_GRP_NUM; loop++)
            {
                SYS_TMM_QUE_ID_FR_GROUP(queue_base, (p_usw_queue_master[lchip]->group_id_ets[chan_id].group_id + loop), 1);
                queue_id = queue_base + p_stats_param->queue.queue_id;
                st_param.ptr = ((p_stats_param->stats_en & 0x3) << SYS_QUEUE_STATS_PTR_PKT_TYPE_SHIFT) | queue_id;
                CTC_ERROR_RETURN(sys_usw_flow_stats_clear_stats(lchip, &st_param));
            }
            SYS_TMM_QUE_ID_FR_GROUP(queue_base, SYS_GROUP_ID_BY_CHAN(chan_id), 1);
            queue_id = queue_base + p_stats_param->queue.queue_id;
            st_param.ptr = ((p_stats_param->stats_en & 0x3) << SYS_QUEUE_STATS_PTR_PKT_TYPE_SHIFT) | queue_id;
            CTC_ERROR_RETURN(sys_usw_flow_stats_clear_stats(lchip, &st_param));
        }
        else
        {
            /*stats_ptr bit14&15 for queue stats packet type*/
            st_param.ptr = ((p_stats_param->stats_en & 0x3) << SYS_QUEUE_STATS_PTR_PKT_TYPE_SHIFT) | queue_id;
            CTC_ERROR_RETURN(sys_usw_flow_stats_clear_stats(lchip, &st_param));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_queue_traverse_sch_group(void* node_data, void* user_data)
{
    sys_traverse_t *traverse_data = (sys_traverse_t*)user_data;
    sys_sch_group_node_t *p_sch_group_node = (sys_sch_group_node_t*)node_data;
    SYS_QOS_TRAVERSE_FUNC *fn = (SYS_QOS_TRAVERSE_FUNC*)traverse_data->data1;
    uint16 group_id = 0;
    uint8 lchip = traverse_data->value3;
    uint8 queue_id = 0;

    if (p_sch_group_node->chan_valid && traverse_data->value4 == p_sch_group_node->chan_id 
       && p_sch_group_node->grp_index >= (MCHIP_CAP(SYS_CAP_QOS_L0_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_L1_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_L2_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_L3_GRP_NUM)))
    {
        group_id = p_sch_group_node->grp_index - (MCHIP_CAP(SYS_CAP_QOS_L0_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_L1_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_L2_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_L3_GRP_NUM));
        SYS_TMM_QUE_ID_FR_GROUP(traverse_data->value1, group_id, (group_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_GRP_BASE_16Q) ? 1 : 0));
        for (queue_id = 0; queue_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP); queue_id++)
        {
            (*fn)(lchip, traverse_data);
            traverse_data->value1++;
        }
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_INFO,  "chanid : %7d group_id : %5d\n", p_sch_group_node->chan_id, group_id);
    }
    return CTC_E_NONE;
}

int32
_sys_usw_queue_traverse_queue_node(uint8 lchip, uint16 lport,
                                SYS_QOS_TRAVERSE_FUNC fn,
                                void* user_data)
{
    ctc_qos_queue_id_t queue;
    sys_traverse_t traverse_data;
    sys_usw_dmps_port_info_t  dmps_port_info;
    int32  ret = CTC_E_NONE;
    uint16 queue_id = 0;
    uint8  gchip = 0;

    sal_memset(&dmps_port_info, 0 , sizeof(sys_usw_dmps_port_info_t));
    sal_memset(&traverse_data, 0, sizeof(sys_traverse_t));
    sal_memset(&queue, 0, sizeof(ctc_qos_queue_id_t));
    sys_usw_get_gchip_id(lchip, &gchip);
    dmps_port_info.gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
    traverse_data.data  = user_data;
    traverse_data.data1 = &fn;
    traverse_data.value3 = lchip;
    queue.gport = dmps_port_info.gport;
    queue.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;

    for (queue.queue_id = 0; queue.queue_id < p_usw_queue_master[lchip]->queue_num_per_chanel; queue.queue_id++)
    {
        ret = sys_usw_queue_get_queue_id(lchip, &queue, &queue_id);
        if(ret != CTC_E_NONE)
        {
            continue;
        }
        traverse_data.value1 = queue_id;
        fn(lchip, &traverse_data);
    }

    ret = sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &traverse_data.value4);
    if (ret != CTC_E_NONE || SYS_COMMON_USELESS_CHANNEL == traverse_data.value4)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Invalid localphy port \n");
        return CTC_E_INVALID_PORT;
    }
    ctc_vector_traverse(p_usw_queue_master[lchip]->sch_group_vec, (vector_traversal_fn)_sys_usw_queue_traverse_sch_group, &traverse_data);

    return CTC_E_NONE;
}

int32
sys_usw_qos_queue_dump_status(uint8 lchip)
{
    int32  ret = CTC_E_NONE;
    int32  ret_1 = CTC_E_NONE;
    int32  ret_2 = CTC_E_NONE;
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "---------------------Queue allocation---------------------\n");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d\n", "Queue number per port", p_usw_queue_master[lchip]->queue_num_per_chanel);
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "----------------------------------------------------------\n");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10s %-8s\n", "type", "port-id", "Queue Range", "Qbase", "SubQNum");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-----------------------------------------------------------\n");

    if (DRV_FROM_TMM(lchip))
    {
        uint8 is_network = 0;
        uint16 lport = 0;
        uint16 queue_base = 0;
        uint16 internal_chan_start[2] = {0};
        uint16 cpu_mac_channel[SYS_USW_CPU_MAC_NUM] = {MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC1),
                                                          MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC2), MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC3)};
        char   str_buf[32] = "";
        uint8 i = 0;

        ret_1 = sys_usw_port_api_get_internal_chan_start(lchip, 0, &internal_chan_start[0]);
        if(CTC_E_NONE != ret_1)
        {
            sal_sprintf(str_buf, "%s%d", "0~", MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0) * 8 -1);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "port", "0~255", str_buf,
                                MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL), MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP));
        }
        else if (0 != internal_chan_start[0])
        {
            sal_sprintf(str_buf, "%s%d", "0~", internal_chan_start[0] * 8 -1);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "port", "0~255", str_buf,
                                MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL), MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP));
        }

        memset(str_buf, 0, sizeof(str_buf));
        ret_2 = sys_usw_port_api_get_internal_chan_start(lchip, 1, &internal_chan_start[1]);
        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM), 0, 0);
        if(CTC_E_NONE != ret_2)
        {
            sal_sprintf(str_buf, "%d%s%d", queue_base, "~", queue_base + (MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0) * 8) -1);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "port", "0~255", str_buf,
                                queue_base, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP));
        }
        else if (MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM) != internal_chan_start[1])
        {
            sal_sprintf(str_buf, "%d%s%d", queue_base, "~", queue_base + (internal_chan_start[1] - MCHIP_CAP(SYS_CAP_PER_DP_CHANNEL_NUM))* 8 -1);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "port", "0~255", str_buf,
                                queue_base, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP));
        }

        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_CHANID_ILOOP), 0, 0);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "iloop", "alloc", "-",
                              queue_base, 8);

        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_CHANID_ELOOP), 0, 0);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "eloop", "alloc", "-",
                              queue_base, 8);

        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_CHANID_OAM), 0, 0);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10d %-11s %-10d %8d\n", "Rx OAM", SYS_RSV_PORT_OAM_CPU_ID, "-",
                              queue_base, 8);

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "Local CPU(DMA)", "-", "2048~2175",
                              MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP), 8);
        for (i = 0; i < SYS_USW_CPU_MAC_NUM; i++)
        {
            if (MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx)
            {
                ret = MCHIP_DMPS(lchip)->cpumac_get_lport_info_by_inner_idx(lchip,i,&lport,&is_network);
            }
            if (!is_network)
            {
                SYS_QOS_QUE_BASE(queue_base, cpu_mac_channel[i], 0, 0);
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "Local CPU(ETH)", "-", "-", queue_base, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP));
            }
        }

        memset(str_buf, 0, sizeof(str_buf));
        SYS_QOS_QUE_BASE(queue_base, MCHIP_CAP(SYS_CAP_CHANNEL_NUM) - 1, 0, 0);
        queue_base += MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP);
        sal_sprintf(str_buf, "%d%s", queue_base, "~2047");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "extend queue", "0~255", str_buf,
                                queue_base, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "extend queue", "0~255", "2176~8191",
                                  2176, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "extend queue", "0~255", "8192~11263",
                                    8192, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP_16Q));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-11s %-10d %8d\n", "ctl queue", "0~255", "11264~12287",
                                MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC), 4);
    }
    else
    {

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10d %8d\n", "network port", "0~63", "0~511",
                              MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NORMAL), p_usw_queue_master[lchip]->queue_num_per_chanel);

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10d %8d\n", "iloop", "alloc", "512~639",
                              MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC), 8);

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10d %8d\n", "eloop", "alloc", "512~639",
                              MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC), 8);

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10d %-10s %-10d %8d\n", "Rx OAM", SYS_RSV_PORT_OAM_CPU_ID, "512~639",
                              MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC), 8);

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10d %8d\n", "Local CPU(DMA)", "-", "640~767",
                              MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP), 8);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10s %8d\n", "Local CPU(ETH)", "specific", "0",
                              "-",
                              p_usw_queue_master[lchip]->queue_num_per_chanel);

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10d %8d\n", "ctl queue", "0~63", "768~1023",
                              MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC), 4);
        if (DRV_IS_DUET2(lchip))
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10d %8d\n", "extend queue", "0~63", "1024~1279",
                                  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT), MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP));
        }
        else
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s %-10s %-10s %-10d %8d\n", "extend queue", "0~63", "1024~4095",
                                  MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT), MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP));
        }
    }
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");

    return ret;
}

int32
_sys_usw_qos_dump_status(uint8 lchip)
{
    sys_usw_qos_policer_dump_status(lchip);
    sys_usw_qos_queue_dump_status(lchip);
    sys_usw_qos_shape_dump_status(lchip);
    sys_usw_qos_sched_dump_status(lchip);
    sys_usw_qos_drop_dump_status(lchip);

    return CTC_E_NONE;
}

int32
_sys_usw_qos_queue_dump(uint8 lchip, uint16 start, uint16 end, uint8 detail)
{
    uint16 queue_id = 0;
    uint8 que_offset = 0;
    uint32 cmd = 0;
    uint16 channel = 0;
    uint8 stats_en = 0;
    uint32 token_thrd = 0;
    uint32 token_rate = 0;
    uint8 is_pps = 0;
    uint8 queue_type = 0;
    uint16 ext_grp_id = 0;
    uint32 rate_hw = 0;
    uint32 thrd_hw = 0;
    sys_queue_node_t* p_queue_node = NULL;
    sys_queue_group_node_t* p_group_node = NULL;
    sys_group_meter_profile_t* p_meter_profile = NULL;
    ds_t ds;

    CTC_MAX_VALUE_CHECK(start, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) - 1);
    CTC_MAX_VALUE_CHECK(end, MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) - 1);

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\nQueue information:\n");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7s %-7s %-7s %-7s %-8s %-7s\n", "queue", "offset", "channel", "group","stats-en","shp-en");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "---------------------------------------------------------\n");

    for (queue_id = start; queue_id <= end && queue_id < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM); queue_id++)
    {
        p_queue_node = ctc_vector_get(p_usw_queue_master[lchip]->queue_vec,queue_id);
        if (NULL == p_queue_node)
        {
            que_offset = queue_id % 8;
            continue;
        }
        else
        {
            que_offset = p_queue_node->offset;
        }

        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            int32 ret = CTC_E_NONE;
            stats_en = 1;
            ret = sys_usw_get_channel_by_queue_id(lchip, queue_id, &channel);

            if (queue_id >= MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC))
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7d %-7d %-7d %-7s %-8d %-7d\n", queue_id, que_offset, channel,
                                      "-", stats_en, p_queue_node->shp_en);
            }
            else
            {
                SYS_TMM_GROUP_ID(ext_grp_id, queue_id, 1);
                if (ret == CTC_E_NONE)
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7d %-7d %-7d %-7d %-8d %-7d\n", queue_id, que_offset, channel,
                                          ext_grp_id, stats_en, p_queue_node->shp_en);
                }
                else
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7d %-7d %-7s %-7d %-8d %-7d\n", queue_id, que_offset, "-",
                                          ext_grp_id, stats_en, p_queue_node->shp_en);
                }
            }

        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_get_channel_by_queue_id(lchip, queue_id, &channel));
            CTC_ERROR_RETURN(_sys_usw_queue_get_stats_enable(lchip, queue_id, &stats_en));

            if (SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_EXT_QUEUE(queue_id))
            {
                if (SYS_IS_EXT_QUEUE(queue_id))
                {
                    SYS_EXT_GROUP_ID(queue_id, ext_grp_id);
                    p_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, ext_grp_id);
                    if (NULL == p_group_node)
                    {
                        continue;
                    }
                    if (p_group_node->chan_id == 0xFF)
                    {
                        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7d %-7d %-7s %-7d %-8d %-7d\n", queue_id, que_offset, "-",
                                              SYS_GROUP_ID(queue_id), stats_en, p_queue_node->shp_en);
                    }
                    else
                    {
                        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7d %-7d %-7d %-7d %-8d %-7d\n", queue_id, que_offset, p_group_node->chan_id,
                                              SYS_GROUP_ID(queue_id), stats_en, p_queue_node->shp_en);
                    }
                }
                else
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7d %-7d %-7d %-7d %-8d %-7d\n", queue_id, que_offset, channel,
                                          SYS_GROUP_ID(queue_id), stats_en, p_queue_node->shp_en);
                }
            }
            else
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-7d %-7d %-7d %-7s %-8d %-7d\n", queue_id, que_offset, channel, "-",
                                      stats_en, p_queue_node->shp_en);
            }
        }
    }

    if (start == end)
    {
        queue_id = start;
    }

    if ((start == end) && p_queue_node)
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\nQueue shape:\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------------\n");

        if (DRV_FROM_TMM(lchip))
        {
            if (MCHIP_QOS(lchip)->qos_shape_get_que_shape_profile)
            {
                ctc_qos_shape_queue_t que_shape;
                sal_memset(&que_shape, 0,  sizeof(ctc_qos_shape_queue_t));
                MCHIP_QOS(lchip)->qos_shape_get_que_shape_profile(lchip, queue_id, p_queue_node->offset,(void *)&que_shape);
                if (que_shape.cir)
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kbps/pps)\n", "CIR", que_shape.cir);
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kb/pkt)\n", "CBS", que_shape.cbs);
                }
                else
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "No CIR Bucket, all packet always mark as yellow!\n");
                }
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %s\n", "Shape mode", que_shape.pps_en ? "PPS" : "BPS");
                if (que_shape.enable)
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kbps/pps)\n", "PIR", que_shape.pir);
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kb/pkt)\n", "PBS", que_shape.pbs);
                }
                else
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "No PIR Bucket\n");
                }
            }
        }
        else
        {
            is_pps = sys_usw_queue_shp_get_channel_pps_enbale(lchip, channel);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %s\n", "Shape mode", is_pps? "PPS" : "BPS");

            if (SYS_IS_EXT_QUEUE(queue_id))
            {
                SYS_EXT_GROUP_ID(queue_id, ext_grp_id);
                p_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, ext_grp_id);
                if (NULL == p_group_node)
                {
                    return CTC_E_NONE;
                }
                CTC_MAX_VALUE_CHECK(p_queue_node->offset, SYS_GRP_SHP_CBUCKET_NUM - 1);
                p_meter_profile = p_group_node->p_meter_profile;

                if (!p_queue_node->shp_en || (p_meter_profile == NULL) || p_meter_profile->c_bucket[que_offset].cir_type == SYS_QUEUE_GRP_SHP_CIR_TYPE_CIR_FAIL)
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "No CIR Bucket, all packet always mark as yellow!\n");
                }
                else if (p_meter_profile->c_bucket[que_offset].cir_type == SYS_QUEUE_GRP_SHP_CIR_TYPE_CIR_USER)
                {
                    sys_usw_qos_map_token_rate_hw_to_user(lchip, is_pps, p_meter_profile->c_bucket[que_offset].rate, &token_rate, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_BIT_WIDTH),
                                                          p_usw_queue_master[lchip]->que_shp_update_freq, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_PACKET_BYTES));
                    _sys_usw_qos_map_token_thrd_hw_to_user(lchip, &token_thrd , p_meter_profile->c_bucket[que_offset].thrd, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH));
                    SYS_QOS_GET_SHAPE_TOKEN_THRD(is_pps, token_thrd);
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kbps/pps)\n", "CIR", token_rate);
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kb/pkt)\n", "CBS", token_thrd);
                }
            }

            if (p_queue_node->shp_en && p_queue_node->shp_profile_id)
            {
                if (SYS_IS_NETWORK_BASE_QUEUE(queue_id) && p_queue_node->meter_profile_id)
                {
                    sal_memset(&ds, 0, sizeof(ds));
                    CTC_ERROR_RETURN(sys_usw_queue_get_queue_type_by_queue_id(lchip, p_queue_node->queue_id, &queue_type));
                    CTC_ERROR_RETURN(_sys_usw_queue_shp_decode_queue_shape_meter_profile(lchip, p_queue_node->meter_profile_id, ds, &rate_hw, &thrd_hw));
                    sys_usw_qos_map_token_rate_hw_to_user(lchip, is_pps, rate_hw, &token_rate, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_BIT_WIDTH),
                                                          p_usw_queue_master[lchip]->que_shp_update_freq, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_PACKET_BYTES));
                    _sys_usw_qos_map_token_thrd_hw_to_user(lchip, &token_thrd , thrd_hw, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH));
                    SYS_QOS_GET_SHAPE_TOKEN_THRD(is_pps, token_thrd);
                    if (token_rate)
                    {
                        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kbps/pps)\n", "CIR", token_rate);
                        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kb/pkt)\n", "CBS", token_thrd);
                    }
                    else
                    {
                        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "No CIR Bucket, all packet always mark as yellow!\n");
                    }
                }
                sal_memset(&ds, 0, sizeof(ds));
                CTC_ERROR_RETURN(sys_usw_queue_get_queue_type_by_queue_id(lchip, p_queue_node->queue_id, &queue_type));
                CTC_ERROR_RETURN(_sys_usw_queue_shp_decode_queue_shape_profile(lchip, queue_type, p_queue_node->shp_profile_id, ds, &rate_hw, &thrd_hw));
                sys_usw_qos_map_token_rate_hw_to_user(lchip, is_pps, rate_hw, &token_rate, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_BIT_WIDTH),
                                                      p_usw_queue_master[lchip]->que_shp_update_freq, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_PACKET_BYTES));
                _sys_usw_qos_map_token_thrd_hw_to_user(lchip, &token_thrd , thrd_hw, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH));
                SYS_QOS_GET_SHAPE_TOKEN_THRD(is_pps, token_thrd);
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kbps/pps)\n", "PIR", token_rate);
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d (kb/pkt)\n", "PBS", token_thrd);
            }
            else
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "No PIR Bucket\n");
            }
        }
    }

    if (start == end)
    {
        ctc_qos_sched_group_t grp_sched;
        ctc_qos_sched_queue_t  queue_sched;
        uint16 reason_id = 0;
        uint32 group_id = 0;

        sal_memset(&queue_sched, 0,  sizeof(queue_sched));
        sal_memset(&grp_sched, 0, sizeof(grp_sched));
        queue_sched.cfg_type = CTC_QOS_SCHED_CFG_EXCEED_CLASS;
        CTC_ERROR_RETURN(sys_usw_queue_sch_get_queue_sched(lchip, queue_id , &queue_sched));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\nQueue Scheduler:\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------------\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d \n", "Queue Class(Yellow)", queue_sched.exceed_class);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d \n", "Weight", queue_sched.exceed_weight);

        if ((SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_EXT_QUEUE(queue_id) || (DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip))))
        {
            grp_sched.queue_class = queue_sched.exceed_class;
            SYS_TMM_GROUP_ID(group_id, queue_id, 1);
            SYS_SUB_GRP_TO_LVL_GRP(grp_sched.group_id, CTC_QOS_SCHED_GROUP_LVL_Q, lchip, group_id);
            sys_usw_queue_sch_get_group_sched(lchip, SYS_GROUP_ID(queue_id), &grp_sched);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "Queue Class(Yellow) %d priority: %d\n", queue_sched.exceed_class, grp_sched.class_priority);
        }
        if(SYS_IS_CPU_QUEUE(start))
        {
            uint8 sub_queue_id = 0;
            uint8 sub_queue_id_min = 0;
            uint8 sub_queue_id_max = 0;
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\nCPU Reason:\n");
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------------\n");
            sub_queue_id = start - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXCP);
            for(reason_id = 0; reason_id < CTC_PKT_CPU_REASON_MAX_COUNT; reason_id ++)
            {
                sub_queue_id_min = p_usw_queue_master[lchip]->cpu_reason[reason_id].sub_queue_id & 0xFF;
                sub_queue_id_max = (reason_id == CTC_PKT_CPU_REASON_C2C_PKT) ? (sub_queue_id_min + MCHIP_CAP(SYS_CAP_QOS_REASON_C2C_MAX_QUEUE_NUM) - 1)
                    : (CTC_IS_BIT_SET(p_usw_queue_master[lchip]->cpu_reason[reason_id].sub_queue_id, SYS_REASON_PRI_ENQ_SHIFT) ? (sub_queue_id_min + MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM) - 1) : sub_queue_id_min);
                if(sub_queue_id_min <= sub_queue_id && sub_queue_id <= sub_queue_id_max)
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %d \n", sys_usw_reason_2Str(reason_id), reason_id);
                }
            }
        }
    }

    if (start == end)
    {
        uint32 wred_profile = 0;
        uint8 wred = 0;
        uint8 wtd  = 0;
        uint32 value = 0;
        uint32 index = 0;
        uint16 wredMaxThrd[4];
        uint16 wredMinThrd[4];
        uint16 ecnthreshold[4];
        uint16 drop_prob[4];
        DsErmAqmQueueCfg_m erm_aqm_queue_cfg;
        DsErmQueueCfg_m erm_queue_cfg;
        DsErmQueueLimitedThrdProfile_m erm_queue_thrd_profile;
        DsErmAqmQueueThrdProfile_m erm_aqm_thrd_profile;
        uint8 cngest = 0;
        uint8 sc = 0;
        uint8 tc = 0;
        uint32 field_value = 0;
        uint8 drop_factor[16] = {7,8,9,10,0,0,0,0,0,6,5,4,3,2,1,0};
        uint8 cngest_level = 0;
        uint8 temp_value = 0;

        sal_memset(&erm_aqm_queue_cfg, 0, sizeof(DsErmAqmQueueCfg_m));
        sal_memset(&erm_queue_cfg, 0, sizeof(DsErmQueueCfg_m));
        sal_memset(&erm_queue_thrd_profile, 0, sizeof(DsErmQueueLimitedThrdProfile_m));
        sal_memset(&erm_aqm_thrd_profile, 0, sizeof(DsErmAqmQueueThrdProfile_m));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\nQueue Drop:\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------------\n");

        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            index = queue_id >> 2;
            cmd = DRV_IOR(DsErmAqmQueueThrdProfileId_t, DsErmAqmQueueThrdProfileId_g_0_aqmThrdProfileId_f + (queue_id&0x3));
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &wred_profile));
            wred = wred_profile;
        }
        else
        {
            if (SYS_IS_NETWORK_BASE_QUEUE(queue_id) || SYS_IS_EXT_QUEUE(queue_id))
            {
                index = (queue_id >= MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT))
                ? ((queue_id - MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)) + MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_MISC))
                : queue_id;
                cmd = DRV_IOR(DsErmAqmQueueCfg_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_aqm_queue_cfg));

                wred_profile = GetDsErmAqmQueueCfg(V, queueThrdProfId_f , &erm_aqm_queue_cfg);
                wred = (wred_profile != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM));
            }

        }

        sys_usw_queue_get_sc_tc(lchip, p_queue_node, &sc, &tc);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "Mapped tc", tc);
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-30s: %d\n", "Mapped sc", sc);

        cngest_level = p_usw_queue_master[lchip]->egs_pool[sc].egs_congest_level_num;

        if (wred)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %s\n", "Drop Mode", "WRED");

            cmd = DRV_IOR(DsErmAqmQueueThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, wred_profile, cmd, &erm_aqm_thrd_profile));
            wredMaxThrd[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMaxLen_f , &erm_aqm_thrd_profile);
            wredMaxThrd[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMaxLen_f , &erm_aqm_thrd_profile);
            wredMaxThrd[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMaxLen_f , &erm_aqm_thrd_profile);
            wredMaxThrd[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMaxLen_f , &erm_aqm_thrd_profile);
            wredMinThrd[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f , &erm_aqm_thrd_profile);
            wredMinThrd[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMinLen_f , &erm_aqm_thrd_profile);
            wredMinThrd[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMinLen_f , &erm_aqm_thrd_profile);
            wredMinThrd[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMinLen_f , &erm_aqm_thrd_profile);
            drop_prob[0] = GetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f , &erm_aqm_thrd_profile);
            drop_prob[1] = GetDsErmAqmQueueThrdProfile(V, g_1_wredProbFactor_f , &erm_aqm_thrd_profile);
            drop_prob[2] = GetDsErmAqmQueueThrdProfile(V, g_2_wredProbFactor_f , &erm_aqm_thrd_profile);
            drop_prob[3] = GetDsErmAqmQueueThrdProfile(V, g_3_wredProbFactor_f , &erm_aqm_thrd_profile);

            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-29s : /%-8u/%-8u/%-8u\n", "MaxThrd",  wredMaxThrd[0] * 8, wredMaxThrd[1] * 8, wredMaxThrd[2] * 8);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-29s : /%-8u/%-8u/%-8u\n", "MinThrd",  wredMinThrd[0] * 8, wredMinThrd[1] * 8, wredMinThrd[2] * 8);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-29s : /%-8u/%-8u/%-8u \n", "Drop_prob", drop_prob[0], drop_prob[1], drop_prob[2]);
        }

        index = queue_id;

        if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
        {
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DsErmQueueLimitedThrdProfile_g_0_queueLimitedThrd_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &value));
            wtd = (value != 0x3FFF);
        }
        else
        {
            cmd = DRV_IOR(DsErmQueueCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_cfg));
            value = GetDsErmQueueCfg(V, queueLimitedThrdProfId_f , &erm_queue_cfg);
            wtd = (value != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM));
        }

        if (wtd)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: %s\n", "Drop Mode", "WTD");
            index = DRV_FROM_TMM(lchip) ? queue_id : (value << 2);
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DsErmQueueLimitedThrdProfile_g_0_queueLimitedAutoEn_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &field_value));
            if(field_value == 1)
            {
                cngest_level = 1;
                cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
                CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_thrd_profile));
                wredMaxThrd[0] = GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedFactor_f , &erm_queue_thrd_profile);
                wredMaxThrd[1] = GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedFactor_f , &erm_queue_thrd_profile);
                wredMaxThrd[2] = GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedFactor_f , &erm_queue_thrd_profile);
                wredMaxThrd[3] = GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedFactor_f , &erm_queue_thrd_profile);

                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-30s: /%-8u/%-8u/%-8u\n",
                "DropFactor", drop_factor[wredMaxThrd[0]], drop_factor[wredMaxThrd[1]], drop_factor[wredMaxThrd[2]]);
            }
            else if(cngest_level > 0)
            {
                for (cngest = 0; cngest < cngest_level; cngest++)
                {
                    temp_value = (p_usw_queue_master[lchip]->resrc_check_mode != 0) ? (cngest + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM)-cngest_level)):0;
                    cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
                    index = DRV_FROM_TMM(lchip) ? queue_id : ((value << 2) + temp_value);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_thrd_profile));

                    wredMaxThrd[0] = GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedThrd_f , &erm_queue_thrd_profile);
                    wredMaxThrd[1] = GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedThrd_f , &erm_queue_thrd_profile);
                    wredMaxThrd[2] = GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedThrd_f , &erm_queue_thrd_profile);
                    wredMaxThrd[3] = GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedThrd_f , &erm_queue_thrd_profile);

                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "Congest:%d %-19s : /%-8u/%-8u/%-8u\n",
                                                    cngest, "DropThrd", wredMaxThrd[0] * 8, wredMaxThrd[1] * 8, wredMaxThrd[2] * 8);
                }

            }
            if(cngest_level > 0)
            {
                for (cngest = 0; cngest < cngest_level; cngest++)
                {
                    temp_value = (p_usw_queue_master[lchip]->resrc_check_mode != 0) ? (cngest + (MCHIP_CAP(SYS_CAP_QOS_CONGEST_LEVEL_NUM)-cngest_level)):0;
                    cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
                    index = DRV_FROM_TMM(lchip) ? queue_id : ((value << 2) + temp_value);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &erm_queue_thrd_profile));

                    ecnthreshold[0] = GetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f , &erm_queue_thrd_profile);
                    ecnthreshold[1] = GetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f , &erm_queue_thrd_profile);
                    ecnthreshold[2] = GetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f , &erm_queue_thrd_profile);
                    ecnthreshold[3] = GetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f , &erm_queue_thrd_profile);

                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "Congest:%d %-19s : /%-8u/%-8u/%-8u\n",
                                                    cngest, "EcnThrd", ecnthreshold[0] * 8, ecnthreshold[1] * 8, ecnthreshold[2] * 8);
                }
            }
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_group_dump(uint8 lchip, uint32 start, uint32 end, uint8 detail)
{
    uint32 group_id = 0;
    uint32 token_thrd = 0;
    uint32 token_rate = 0;
    uint8 loop = 0;
    uint8 loop_num = 0;
    uint8 is_pps = 0;
    uint8  level = 0;
    uint32 sub_grp_id = 0;
    uint32 max_grp = 0;
    sys_queue_group_node_t  * p_group_node = NULL;

    if(DRV_FROM_TMM(lchip))
    {
        SYS_LVL_GRP_TO_SUB_GRP(start, level, sub_grp_id);
        SYS_CHECK_SUB_GROUP_ID(sub_grp_id, level);
    }
    else
    {
        CTC_MAX_VALUE_CHECK(start, ((MCHIP_CAP(SYS_CAP_QOS_BASE_QUEUE_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM)) - 1));
        CTC_MAX_VALUE_CHECK(end, ((MCHIP_CAP(SYS_CAP_QOS_BASE_QUEUE_GRP_NUM) + MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM)) - 1));
    }

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "Group information:\n");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-10s %-10s", "group", "channel");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-8s %-15s %-15s ", "shp_en", "pir(kbps/pps)", "pbs(kb/pkt)");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "---------------------------------------------------------------\n");

    max_grp = DRV_FROM_TMM(lchip) ? MCHIP_CAP(SYS_CAP_QOS_LVL_GRP_NUM) : MCHIP_CAP(SYS_CAP_QOS_GROUP_NUM);
    for (group_id = start; group_id <= end && group_id < max_grp; group_id++)
    {
        token_thrd = 0;
        token_rate = 0;
        if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_shape_get_grp_shape_profile
            && MCHIP_QOS(lchip)->qos_queue_get_chan_by_grp_id)
        {
            uint8 shp_en = 0;
            uint16 channel = 0;
            int32 ret = CTC_E_NONE;
            MCHIP_QOS(lchip)->qos_shape_get_grp_shape_profile(lchip, group_id, &token_rate, &token_thrd, &is_pps, &shp_en);
            ret = MCHIP_QOS(lchip)->qos_queue_get_chan_by_grp_id(lchip, group_id, &channel);
            if(ret == CTC_E_NONE)
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "0x%-10x %-10d %-8d %-15u %-15u\n", group_id,
                                      channel, shp_en, token_rate, token_thrd);
            }
            else
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "0x%-10x %-10s %-8d %-15u %-15u\n", group_id,
                                      "-", shp_en, token_rate, token_thrd);
            }
        }
        else
        {
            if (group_id < MCHIP_CAP(SYS_CAP_QOS_BASE_QUEUE_GRP_NUM))
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-10d %-10d %-8s %-15s %-15s\n", group_id,
                                      group_id, "-", "-", "-");
            }
            else
            {
                p_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, (group_id - MCHIP_CAP(SYS_CAP_QOS_BASE_QUEUE_GRP_NUM)));
                if (NULL == p_group_node)
                {
                    continue;
                }
                is_pps = sys_usw_queue_shp_get_channel_pps_enbale(lchip, p_group_node->chan_id);
                if (p_group_node->shp_bitmap && p_group_node->p_shp_profile)
                {
                    sys_usw_qos_map_token_rate_hw_to_user(lchip, is_pps, p_group_node->p_shp_profile->bucket_rate, &token_rate, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_BIT_WIDTH),
                                                          p_usw_queue_master[lchip]->que_shp_update_freq, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_PACKET_BYTES));
                    _sys_usw_qos_map_token_thrd_hw_to_user(lchip, &token_thrd, p_group_node->p_shp_profile->bucket_thrd, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH));
                }
                SYS_QOS_GET_SHAPE_TOKEN_THRD(is_pps, token_thrd);
                if (p_group_node->chan_id == 0xFF)
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-10d %-10s %-8d %-15u %-15u\n", group_id,
                                          "-", CTC_IS_BIT_SET(p_group_node->shp_bitmap, MCHIP_CAP(SYS_CAP_QOS_QUEUE_PIR_BUCKET)), token_rate, token_thrd);
                }
                else
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-10d %-10d %-8d %-15u %-15u\n", group_id,
                                          p_group_node->chan_id, CTC_IS_BIT_SET(p_group_node->shp_bitmap, MCHIP_CAP(SYS_CAP_QOS_QUEUE_PIR_BUCKET)), token_rate, token_thrd);
                }
            }
        }
    }

    if ((start == end) && DRV_FROM_TMM(lchip))
    {
        uint8  level = 0;
        uint8  cir_shp_en = 0;
        uint8  pir_shp_en = 0;
        uint32 cir_token_thrd = 0;
        uint32 cir_token_rate = 0;
        group_id = start;

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "Group node shp information:\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15s", "group_node");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-8s %-15s %-15s %-15s %-15s ", "shp_en", "cir(kbps/pps)", "cbs(kb/pkt)", "pir(kbps/pps)", "pbs(kb/pkt)");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "--------------------------------------------------------------------------------------\n");

        SYS_LVL_GRP_TO_SUB_GRP(group_id, level, sub_grp_id);
        loop_num = (CTC_QOS_SCHED_GROUP_LVL_Q == level) ? MCHIP_CAP(SYS_CAP_QOS_QUE_GRP_NODE_NUM) : MCHIP_CAP(SYS_CAP_QOS_LX_GRP_NODE_NUM);
        for (loop = 0;  loop < loop_num; loop++)
        {
            if (MCHIP_QOS(lchip)->qos_shape_get_grp_node_shape_profile)
            {
                MCHIP_QOS(lchip)->qos_shape_get_grp_node_shape_profile(lchip, group_id, loop, 1,
                                                                       &cir_token_rate, &cir_token_thrd, &is_pps, &cir_shp_en);
                MCHIP_QOS(lchip)->qos_shape_get_grp_node_shape_profile(lchip, group_id, loop, 0,
                                                                       &token_rate, &token_thrd, &is_pps, &pir_shp_en);

                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15d %-8d %-15u %-15u ", loop,
                                      (cir_shp_en || pir_shp_en), cir_token_rate, cir_token_thrd);
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-15u %-15u \n", token_rate, token_thrd);
            }
        }
    }

    if (start == end)
    {
        ctc_qos_sched_group_t  group_sched;
        sal_memset(&group_sched, 0, sizeof(ctc_qos_sched_group_t));
        group_id = start;

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\nGroup Scheduler:\n");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------------\n");

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-12s %-10s %-6s\n", "Queue-Class", "Class-PRI", "Weight");

        loop_num = (group_id >= MCHIP_CAP(SYS_CAP_QOS_BASE_QUEUE_GRP_NUM)) ? MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP) : MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_CHAN) ;
        loop_num = DRV_FROM_TMM(lchip) ? 1 : loop_num;
        for (loop = 0;  loop < loop_num; loop++)
        {
            group_sched.queue_class = loop;
            group_sched.group_id = group_id;
            sys_usw_queue_sch_get_group_sched(lchip, group_id, &group_sched);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-12d %-10d %-6d\n", loop, group_sched.class_priority, group_sched.weight);
        }
    }

    if ((start == end) && DRV_FROM_TMM(lchip))
    {
        if (MCHIP_QOS(lchip)->qos_sch_dump_sched_group_child_list)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "\nsch group child list:\n");
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "-------------------------------------\n");
            MCHIP_QOS(lchip)->qos_sch_dump_sched_group_child_list(lchip, group_id);
        }
    }

    return CTC_E_NONE;
}

int32
_sys_usw_qos_port_dump(uint8 lchip, uint16 start, uint16 end, uint8 detail)
{
    uint16 channel = 0;
    uint16 port = 0;
    uint16 lport = 0;
    uint32 cmd;
    uint8  shp_en = 0;
    uint32 token_thrd = 0;
    uint32 token_thrd_shift = 0;
    uint32 token_rate = 0;
    uint32 token_rate_frac = 0;
    uint8 is_pps = 0;
    uint8 gchip = 0;
    uint16 group_id = 0;
    uint32 index = 0;
    uint8 bpe_en = 0;
    uint32 gport = 0;
    uint32 port_type = 0;
    sys_dmps_port_info_t  port_info;
    sys_queue_group_node_t* p_group_node = NULL;

    sys_usw_get_gchip_id(lchip, &gchip);
    if (FALSE == sys_usw_chip_is_local(lchip, gchip))
    {
        return CTC_E_INVALID_CHIP_ID;
    }
    if ((start >= MCHIP_CAP(SYS_CAP_PER_SLICE_PORT_NUM) * MCHIP_CAP(SYS_CAP_LOCAL_SLICE_NUM)) ||
        (end >= MCHIP_CAP(SYS_CAP_PER_SLICE_PORT_NUM) * MCHIP_CAP(SYS_CAP_LOCAL_SLICE_NUM)))
    {
        return CTC_E_INVALID_PORT;
    }

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "Port information:\n");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "%-10s %-10s %-10s %-15s %-15s %-7s\n","port","channel", "shp-en", "pir(kbps/pps)", "pbs(kb/pkt)","shp_mode");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "---------------------------------------------------------------------------\n");

    for (port = start; port <= end && port < SYS_USW_MAX_PORT_NUM_PER_CHIP; port++)
    {
        lport = port;

        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport);
        sys_usw_qos_get_mux_port_enable(lchip, gport, &bpe_en);
        _sys_usw_get_channel_by_port(lchip, gport, &channel);
        sal_memset(&port_info, 0 , sizeof(port_info));
        port_info.lport = lport;
        sys_usw_dmps_db_api_get_port_property(lchip, &port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type);
        if (bpe_en && SYS_DMPS_NETWORK_PORT != port_type)
        {
            sys_extend_que_node_t port_extender_node;
            sys_extend_que_node_t* p_port_extender_node = NULL;
            sal_memset(&port_extender_node, 0, sizeof(port_extender_node));
            port_extender_node.type = SYS_EXTEND_QUE_TYPE_BPE;
            port_extender_node.lchip = lchip;
            port_extender_node.lport = lport;
            port_extender_node.channel = channel;
            p_port_extender_node = sys_usw_port_extender_lookup(lchip, &port_extender_node);
            if (NULL == p_port_extender_node)
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                return CTC_E_NOT_EXIST;
            }

            if (DRV_FROM_TMM(lchip))
            {
                uint32 lvl_group_id = 0;
                SYS_SUB_GRP_TO_LVL_GRP(lvl_group_id, CTC_QOS_SCHED_GROUP_LVL_Q, lchip, p_port_extender_node->group_id);
                if (MCHIP_QOS(lchip)->qos_shape_get_grp_shape_profile)
                {
                    MCHIP_QOS(lchip)->qos_shape_get_grp_shape_profile(lchip, lvl_group_id, &token_rate,
                                                                             &token_thrd, &is_pps, &shp_en);
                }
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "0x%04x     %-10d %-10d %-15u %-15u %-7s\n", SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport),
                    port_extender_node.channel, shp_en, token_rate, token_thrd, is_pps ? "PPS" : "BPS");
            }
            else
            {
            group_id = p_port_extender_node->group_id;
            p_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, group_id);
            if (NULL == p_group_node)
            {
                continue;
            }

            is_pps = sys_usw_queue_shp_get_channel_pps_enbale(lchip, p_group_node->chan_id);

            /*default value for token_rate and token_thrd*/
            sys_usw_qos_map_token_rate_hw_to_user(lchip, is_pps, (0x3FFFFF << 8 | 0xFF), &token_rate, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_BIT_WIDTH),
                                                    p_usw_queue_master[lchip]->que_shp_update_freq, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_PACKET_BYTES));
            _sys_usw_qos_map_token_thrd_hw_to_user(lchip, &token_thrd ,
                                                    (0xFF << MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH) | 0x1F), MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH));

            if (p_group_node->shp_bitmap && p_group_node->p_shp_profile)
            {
                sys_usw_qos_map_token_rate_hw_to_user(lchip, is_pps, p_group_node->p_shp_profile->bucket_rate, &token_rate, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_BIT_WIDTH),
                                                        p_usw_queue_master[lchip]->que_shp_update_freq, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_PACKET_BYTES));
                _sys_usw_qos_map_token_thrd_hw_to_user(lchip, &token_thrd , p_group_node->p_shp_profile->bucket_thrd, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH));
            }
            SYS_QOS_GET_SHAPE_TOKEN_THRD(is_pps, token_thrd);
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "0x%04x     %-10d %-10d %-15u %-15u %-7s\n",
                                                    SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, lport), p_group_node->chan_id,
            CTC_IS_BIT_SET(p_group_node->shp_bitmap, MCHIP_CAP(SYS_CAP_QOS_QUEUE_PIR_BUCKET)), token_rate, token_thrd, is_pps ? "PPS" : "BPS");
            }
        }
        else
        {
            if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_shape_get_port_shape_profile)
            {
                MCHIP_QOS(lchip)->qos_shape_get_port_shape_profile(lchip, channel, &token_rate, &token_thrd, &is_pps, &shp_en);
            }
            else
            {
                if (channel < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM))
                {
                    DsQMgrNetChanShpProfile_m  net_chan_shp_profile;
                    sal_memset(&net_chan_shp_profile, 0, sizeof(DsQMgrNetChanShpProfile_m));

                    cmd = DRV_IOR(DsQMgrNetChanShpProfile_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, channel, cmd, &net_chan_shp_profile));

                    token_thrd = GetDsQMgrNetChanShpProfile(V, tokenThrd_f, &net_chan_shp_profile);
                    token_thrd_shift = GetDsQMgrNetChanShpProfile(V, tokenThrdShift_f, &net_chan_shp_profile);
                    token_rate_frac = GetDsQMgrNetChanShpProfile(V, tokenRateFrac_f, &net_chan_shp_profile);
                    token_rate = GetDsQMgrNetChanShpProfile(V, tokenRate_f, &net_chan_shp_profile);
                }
                else if (channel < MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0))
                {
                    DsQMgrMiscChanShpProfile_m  misc_chan_shp_profile;
                    sal_memset(&misc_chan_shp_profile, 0, sizeof(DsQMgrMiscChanShpProfile_m));
                    cmd = DRV_IOR(DsQMgrMiscChanShpProfile_t, DRV_ENTRY_FLAG);
                    index = channel - MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &misc_chan_shp_profile));

                    token_thrd = GetDsQMgrMiscChanShpProfile(V, tokenThrd_f, &misc_chan_shp_profile);
                    token_thrd_shift = GetDsQMgrMiscChanShpProfile(V, tokenThrdShift_f, &misc_chan_shp_profile);
                    token_rate_frac = GetDsQMgrMiscChanShpProfile(V, tokenRateFrac_f, &misc_chan_shp_profile);
                    token_rate = GetDsQMgrMiscChanShpProfile(V, tokenRate_f, &misc_chan_shp_profile);
                }
                else if (channel >= MCHIP_CAP(SYS_CAP_CHANID_DMA_RX0) && channel <= MCHIP_CAP(SYS_CAP_CHANID_DMA_RX3))
                {
                    QMgrDmaChanShpProfile_m  dma_chan_shp_profile;
                    sal_memset(&dma_chan_shp_profile, 0, sizeof(QMgrDmaChanShpProfile_m));

                    cmd = DRV_IOR(QMgrDmaChanShpProfile_t, DRV_ENTRY_FLAG);
                    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &dma_chan_shp_profile));

                    token_thrd = GetQMgrDmaChanShpProfile(V, dmaChanShpTokenThrd_f, &dma_chan_shp_profile);
                    token_thrd_shift = GetQMgrDmaChanShpProfile(V, dmaChanShpTokenThrdShift_f, &dma_chan_shp_profile);
                    token_rate_frac = GetQMgrDmaChanShpProfile(V, dmaChanShpTokenRateFrac_f, &dma_chan_shp_profile);
                    token_rate = GetQMgrDmaChanShpProfile(V, dmaChanShpTokenRate_f, &dma_chan_shp_profile);
                }
                else
                {
                    token_thrd = MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD);
                    token_thrd_shift = MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFT);
                    token_rate_frac = MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_FRAC);
                    token_rate = MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE);
                }

                is_pps = sys_usw_queue_shp_get_channel_pps_enbale(lchip, channel);
                shp_en = (token_thrd_shift == MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFT)) ? 0 : 1;

                sys_usw_qos_map_token_rate_hw_to_user(lchip, is_pps, (token_rate << 8 | token_rate_frac)  , &token_rate, MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_RATE_BIT_WIDTH),
                                                      p_usw_queue_master[lchip]->chan_shp_update_freq, MCHIP_CAP(SYS_CAP_QOS_SHP_PPS_PACKET_BYTES));
                _sys_usw_qos_map_token_thrd_hw_to_user(lchip, &token_thrd ,
                                                       (token_thrd << MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH) | token_thrd_shift), MCHIP_CAP(SYS_CAP_QOS_SHP_TOKEN_THRD_SHIFTS_WIDTH));
                SYS_QOS_GET_SHAPE_TOKEN_THRD(is_pps, token_thrd);
            }

            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,  "0x%04x     %-10d %-10d %-15u %-15u %-7s\n",
                                                    SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip, port), channel, shp_en, token_rate, token_thrd, is_pps ? "PPS" : "BPS");
        }
    }

    if (start == end && !DRV_FROM_AT(lchip))
    {
        int32  ret = CTC_E_NONE;
        uint16 queue_id = 0;
        uint16 queue_index = 0;
        uint32 queue_depth = 0;
        uint8  queue_num = 0;
        uint8  stacking_queue_en = 0;
        ctc_qos_queue_id_t queue;
        sal_memset(&queue, 0, sizeof(ctc_qos_queue_id_t));

        sys_usw_qos_get_mux_port_enable(lchip, gport, &bpe_en);
        _sys_usw_queue_get_stacking_enable(lchip, channel, &stacking_queue_en);
        if (stacking_queue_en)
        {
            queue_num = p_usw_queue_master[lchip]->queue_num_per_chanel + (p_usw_queue_master[lchip]->queue_num_per_stk_port == 1 ? 0 : SYS_C2C_QUEUE_NUM);
        }
        else
        {
            queue_num = bpe_en ? p_usw_queue_master[lchip]->queue_num_per_extend_port : 
                p_usw_queue_master[lchip]->queue_num_per_chanel - (p_usw_queue_master[lchip]->queue_num_per_stk_port == 1 ? 1 : 0);
        }

        queue.queue_type = CTC_QUEUE_TYPE_NETWORK_EGRESS;
        queue.gport = gport;

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "\n%-10s %-10s\n","queue-id","queue-depth");
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-------------------------------\n");

        for (queue_index = 0; queue_index < queue_num; queue_index++)
        {
            queue.queue_id = queue_index;
            ret = sys_usw_queue_get_queue_id(lchip, &queue, &queue_id);
            if(ret != CTC_E_NONE)
            {
                continue;
            }

            cmd = DRV_IOR(DsErmQueueCnt_t, DsErmQueueCnt_queueCnt_f);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &queue_depth));
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "%-10d %-10d\n", queue_id, queue_depth);
        }
    }

    return CTC_E_NONE;
}
int32
_sys_usw_qos_service_dump(uint8 lchip, uint16 service_id, uint32 gport)
{
    uint16 queue_id = 0;
    uint16 queue_index = 0;
    uint32 queue_depth = 0;
    uint32 cmd = 0;
    ctc_qos_queue_id_t queue;
    sal_memset(&queue, 0, sizeof(ctc_qos_queue_id_t));

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"show service information:\n");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"============================================================\n");

    queue.queue_type = CTC_QUEUE_TYPE_SERVICE_INGRESS;
    queue.gport = gport;
    queue.service_id = service_id;

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10s %-10s\n", "queue-id", "queue-depth");
    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"-------------------------------\n");

    for (queue_index = 0; queue_index < MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP); queue_index++)
    {
        queue.queue_id = queue_index;
        if(_sys_usw_queue_get_service_queue_id(lchip, 1, &queue, &queue_id))
        {
            continue;
        }
        cmd = DRV_IOR(DsErmQueueCnt_t, DsErmQueueCnt_queueCnt_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_id, cmd, &queue_depth));

        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"%-10d %-10d\n", queue_id, queue_depth);

    }

    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_DUMP,"============================================================\n");

    return CTC_E_NONE;

}

/*for sdk cosim pass*/
int32
sys_usw_queue_init_qmgr(uint8 lchip)
{
    uint32 cmd = 0;
    /*uint8 gchip = 0;*/
    uint32 value = 0;
    uint16 chan_num = 0;
    QWriteCtl_m  q_write_ctl;
    QMgrCtl_m qmgr_ctl;
    /*BufferRetrieveCtl_m buffer_retrieve_ctl;*/
    QWriteOamMiscCtl_m q_oam_ctl;

    sal_memset(&q_write_ctl, 0, sizeof(QWriteCtl_m));
    sal_memset(&qmgr_ctl, 0, sizeof(QMgrCtl_m));
    sal_memset(&q_oam_ctl, 0, sizeof(QWriteOamMiscCtl_m));

    cmd = DRV_IOR(QWriteCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_write_ctl));

    cmd = DRV_IOR(QMgrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmgr_ctl));

    sys_usw_dma_get_packet_rx_chan(lchip, &chan_num);

    if (chan_num == 4)
    {
        SetQWriteCtl(V, cpuQueueMode_f, &q_write_ctl, 1);
        SetQMgrCtl(V, cpuQueueMode_f  , &qmgr_ctl, 1);
    }
    else
    {
        SetQWriteCtl(V, cpuQueueMode_f, &q_write_ctl, 0);
        SetQMgrCtl(V, cpuQueueMode_f  , &qmgr_ctl, 0);
    }

    /*normal stats mode*/
    SetQWriteCtl(V, statsMode_f, &q_write_ctl, 0);
    if (DRV_IS_DUET2(lchip))
    {
        SetQWriteCtl(V, oamFromCpu_f, &q_write_ctl, 1);
    }

    cmd = DRV_IOW(QWriteCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_write_ctl));

    cmd = DRV_IOW(QMgrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmgr_ctl));

/*
    sal_memset(&buffer_retrieve_ctl, 0xFF, sizeof(BufferRetrieveCtl_m));
    sys_usw_get_gchip_id(lchip, &gchip);
    SetBufferRetrieveCtl(V, truncationLenShift_f  , &buffer_retrieve_ctl, 4);
    cmd = DRV_IOW(BufferRetrieveCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &buffer_retrieve_ctl));
*/
    /*QueueAssignmentHyperMode*/
    value = 0;
    cmd = DRV_IOW(FwdLatencyCtl_t, FwdLatencyCtl_queueAssignmentHyperModeDisable_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOR(QWriteOamMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_oam_ctl));

    SetQWriteOamMiscCtl(V, g_1_oamMappedTc_f, &q_oam_ctl, 0);
    SetQWriteOamMiscCtl(V, g_1_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_2_oamMappedTc_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_2_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_6_oamMappedTc_f, &q_oam_ctl, 2);
    SetQWriteOamMiscCtl(V, g_6_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_7_oamMappedTc_f, &q_oam_ctl, 3);
    SetQWriteOamMiscCtl(V, g_7_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_8_oamMappedTc_f, &q_oam_ctl, 4);
    SetQWriteOamMiscCtl(V, g_8_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_10_oamMappedTc_f, &q_oam_ctl, 5);
    SetQWriteOamMiscCtl(V, g_10_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_11_oamMappedTc_f, &q_oam_ctl, 6);
    SetQWriteOamMiscCtl(V, g_11_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, g_12_oamMappedTc_f, &q_oam_ctl, 7);
    SetQWriteOamMiscCtl(V, g_12_oamRemapEn_f, &q_oam_ctl, 1);
    SetQWriteOamMiscCtl(V, ignoreNetChannel_f, &q_oam_ctl, 0);
    cmd = DRV_IOW(QWriteOamMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &q_oam_ctl));
    /* aqm scan pri is high, affect performance */
    cmd = DRV_IOW(QMgrEnqMiscCtl_t, QMgrEnqMiscCtl_cfgAqmScanLowPrioEn_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));

    /* fix tm gg stacking bug 110006*/
    cmd = DRV_IOR(EpeHdrEditReserved_t, EpeHdrEditReserved_reserved_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    CTC_BIT_SET(value, 15);
    value &= 0xffff8fff;
    value |= 0x6000;
    cmd = DRV_IOW(EpeHdrEditReserved_t, EpeHdrEditReserved_reserved_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    /* fix tm bug 112211 and 116555 117271*/
    if (DRV_IS_TSINGMA(lchip))
    {
        cmd = DRV_IOR(QMgrEnqReserved_t, QMgrEnqReserved_reserved_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
        CTC_BIT_SET(value, 3);
        CTC_BIT_SET(value, 4);
        CTC_BIT_SET(value, 5);
        cmd = DRV_IOW(QMgrEnqReserved_t, QMgrEnqReserved_reserved_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_qos_queue_traverse_fprintf_pool(void *node, sys_dump_db_traverse_param_t* user_date)
{
    sal_file_t                  p_file      = (sal_file_t)user_date->value0;
    uint32*                     cnt         = (uint32 *)(user_date->value1);
    uint32*                     mode        = (uint32 *)user_date->value2;
    uint32                      cmd         = 0;
    uint32                      rate_hw     = 0;
    uint32                      thrd_hw     = 0;
    uint8                       i           = 0;
    uint8                       lchip       = user_date->lchip;
    ds_t ds;
    sal_memset(&ds, 0, sizeof(ds));

    if(*mode == SYS_QUEUE_PROFILE)
    {
        sys_queue_shp_profile_t *node_profile = (sys_queue_shp_profile_t *)(((ctc_spool_node_t*)node)->data);
        CTC_ERROR_RETURN(_sys_usw_queue_shp_decode_queue_shape_profile(lchip, node_profile->queue_type, node_profile->profile_id, ds, &rate_hw, &thrd_hw));
        SYS_DUMP_DB_LOG(p_file, "%-9u%-15u%-15u%-15u%-7u\n",*cnt,node_profile->queue_type,thrd_hw,thrd_hw,((ctc_spool_node_t*)node)->ref_cnt);
    }
    else if(*mode == SYS_QUEUE_METER_PROFILE)
    {
        sys_queue_meter_profile_t *node_profile = (sys_queue_meter_profile_t *)(((ctc_spool_node_t*)node)->data);
        CTC_ERROR_RETURN(_sys_usw_queue_shp_decode_queue_shape_meter_profile(lchip, node_profile->profile_id, ds, &rate_hw, &thrd_hw));
        SYS_DUMP_DB_LOG(p_file, "%-9u%-15u%-15u%-7u\n",*cnt,rate_hw,thrd_hw,((ctc_spool_node_t*)node)->ref_cnt);
    }
    else if(*mode == SYS_QUEUE_DROP_WTD_PROFILE)
    {
        sys_queue_drop_wtd_profile_t *node_profile =  (sys_queue_drop_wtd_profile_t *)(((ctc_spool_node_t*)node)->data);
        lchip = node_profile->lchip;
        if(node_profile->profile_id != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM))
        {
            cmd = DRV_IOR(DsErmQueueLimitedThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, node_profile->profile_id << 2, cmd, &ds));
        }
        if(((ctc_spool_node_t*)node)->ref_cnt == 0xFFFFFFFF)
        {
            SYS_DUMP_DB_LOG(p_file, "%-7u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-8ustatic\n",*cnt,
                GetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedFactor_f, &ds), GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedFactor_f, &ds),
                GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedFactor_f, &ds), GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedFactor_f, &ds));
        }
        else
        {
            SYS_DUMP_DB_LOG(p_file, "%-7u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-8u%-6u\n",*cnt,
                GetDsErmQueueLimitedThrdProfile(V, g_3_ecnMarkThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_2_ecnMarkThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_1_ecnMarkThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_0_ecnMarkThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedThrd_f, &ds) * 8, GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedThrd_f, &ds) * 8,
                GetDsErmQueueLimitedThrdProfile(V, g_3_queueLimitedFactor_f, &ds), GetDsErmQueueLimitedThrdProfile(V, g_2_queueLimitedFactor_f, &ds),
                GetDsErmQueueLimitedThrdProfile(V, g_1_queueLimitedFactor_f, &ds), GetDsErmQueueLimitedThrdProfile(V, g_0_queueLimitedFactor_f, &ds),
                ((ctc_spool_node_t*)node)->ref_cnt);
        }
    }
    else if(*mode == SYS_QUEUE_DROP_WRED_PROFILE)
    {
        sys_queue_drop_wred_profile_t *node_profile =  (sys_queue_drop_wred_profile_t *)(((ctc_spool_node_t*)node)->data);
        lchip = node_profile->lchip;
        if((DRV_FROM_TMM(lchip) && node_profile->profile_id)
            || (!DRV_FROM_TMM(lchip) && node_profile->profile_id != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM)))
        {
            cmd = DRV_IOR((DRV_FROM_TMM(lchip) ? DsErmAqmQueueThrdProfile_t : DsErmAqmThrdProfile_t), DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, node_profile->profile_id, cmd, &ds));
       }
        
        SYS_DUMP_DB_LOG(p_file, "%-7u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-9u%-8u%-6u\n",*cnt,
                    GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMinLen_f, &ds) * 8, GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMinLen_f, &ds) * 8,
                    GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMinLen_f, &ds) * 8, GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMinLen_f, &ds) * 8,
                    GetDsErmAqmQueueThrdProfile(V, g_3_wredAvgMaxLen_f, &ds) * 8, GetDsErmAqmQueueThrdProfile(V, g_2_wredAvgMaxLen_f, &ds) * 8,
                    GetDsErmAqmQueueThrdProfile(V, g_1_wredAvgMaxLen_f, &ds) * 8, GetDsErmAqmQueueThrdProfile(V, g_0_wredAvgMaxLen_f, &ds) * 8,
                    GetDsErmAqmQueueThrdProfile(V, g_3_wredProbFactor_f, &ds), GetDsErmAqmQueueThrdProfile(V, g_2_wredProbFactor_f, &ds),
                    GetDsErmAqmQueueThrdProfile(V, g_1_wredProbFactor_f, &ds), GetDsErmAqmQueueThrdProfile(V, g_0_wredProbFactor_f, &ds),
                    ((ctc_spool_node_t*)node)->ref_cnt);
    }
    else if(*mode == SYS_QUEUE_GROUP_PROFILE)
    {
        sys_group_shp_profile_t *node_profile = (sys_group_shp_profile_t *)(((ctc_spool_node_t*)node)->data);
        SYS_DUMP_DB_LOG(p_file, "%-9u%-15u%-15u%-7u\n",*cnt,node_profile->bucket_thrd,node_profile->bucket_rate,((ctc_spool_node_t*)node)->ref_cnt);
    }
    else if(*mode == SYS_QUEUE_GROUP_METER_PROFILE)
    {
        sys_group_meter_profile_t *node_profile = (sys_group_meter_profile_t *)(((ctc_spool_node_t*)node)->data);
        SYS_DUMP_DB_LOG(p_file,"%-5s:%u  refcnt:%u\n","Node",*cnt,((ctc_spool_node_t*)node)->ref_cnt);
        for(i = 0; i < SYS_GRP_SHP_CBUCKET_NUM;i++)
        {
            SYS_DUMP_DB_LOG(p_file,"  rate %u:%u\n",i,node_profile->c_bucket[i].rate);
            SYS_DUMP_DB_LOG(p_file,"  thrd %u:%u\n",i,node_profile->c_bucket[i].thrd);
            SYS_DUMP_DB_LOG(p_file,"  type %u:%u\n",i,node_profile->c_bucket[i].cir_type);
        }
        SYS_DUMP_DB_LOG(p_file, "%s\n", "----------------------------------------------------");
    }
    else if(*mode == SYS_QUEUE_FC_PROFILE || *mode == SYS_QUEUE_PFC_PROFILE || *mode == SYS_QUEUE_FC_DROP_PROFILE|| *mode == SYS_QUEUE_PFC_DROP_PROFILE)
    {
        sys_qos_fc_profile_t *node_profile = (sys_qos_fc_profile_t *)(((ctc_spool_node_t*)node)->data);
        if(((ctc_spool_node_t*)node)->ref_cnt == 0xFFFFFFFF)
        {
            SYS_DUMP_DB_LOG(p_file, "%-7u%-7u%-7u%-7ustatic\n",*cnt,node_profile->xon,node_profile->xoff,node_profile->thrd);
        }
        else
        {
            SYS_DUMP_DB_LOG(p_file, "%-7u%-7u%-7u%-7u%-7u\n",*cnt,node_profile->xon,node_profile->xoff,node_profile->thrd,((ctc_spool_node_t*)node)->ref_cnt);
        }
    }
    else if(*mode == SYS_QUEUE_MIN_PROFILE)
    {
        sys_queue_guarantee_t *node_profile = (sys_queue_guarantee_t *)(((ctc_spool_node_t*)node)->data);
        lchip = node_profile->lchip;
        cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
        DRV_FIELD_IOCTL(lchip, node_profile->profile_id, cmd, &ds);
        if(((ctc_spool_node_t*)node)->ref_cnt == 0xFFFFFFFF)
        {
            SYS_DUMP_DB_LOG(p_file, "%-7u%-9ustatic\n",*cnt,GetDsErmQueueGuaranteedThrdProfile(V, queueGuaranteedThrd_f, &ds));
        }
        else
        {
            SYS_DUMP_DB_LOG(p_file, "%-7u%-9u%-7u\n",*cnt,GetDsErmQueueGuaranteedThrdProfile(V, queueGuaranteedThrd_f, &ds),((ctc_spool_node_t*)node)->ref_cnt);
        }
    }
    else if(*mode == SYS_QUEUE_ENQ_FROFILE)
    {
        uint8 map_type = 0;
        sys_queue_enq_profile_t *node_profile = (sys_queue_enq_profile_t *)(((ctc_spool_node_t*)node)->data);
        SYS_DUMP_DB_LOG(p_file, "%-7u%-6u",*cnt,node_profile->is_mc);
        for(map_type = 0; map_type < SYS_QUE_MAP_TYPE_MAX_NUM; map_type++)
        {
            SYS_DUMP_DB_LOG(p_file, "%-6u%-8u",node_profile->map[map_type].enq_mode, node_profile->map[map_type].offset);
        }
        if(((ctc_spool_node_t*)node)->ref_cnt == 0xFFFFFFFF)
        {
            SYS_DUMP_DB_LOG(p_file, "static");
        }
        else
        {
            SYS_DUMP_DB_LOG(p_file, "%-15u",((ctc_spool_node_t*)node)->ref_cnt);
        }
        SYS_DUMP_DB_LOG(p_file, "\n");
    }
    (*cnt)++;

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_group_node_wb_sync_func(void* array_data, uint32 index, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_queue_group_node_t *p_group_node = (sys_queue_group_node_t *)array_data;
    sys_wb_qos_queue_group_node_t *p_wb_group_node;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = (ctc_wb_data_t *)traversal_data->data;

    max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    p_wb_group_node = (sys_wb_qos_queue_group_node_t *)wb_data->buffer + wb_data->valid_cnt;

    sal_memset(p_wb_group_node, 0, sizeof(sys_wb_qos_queue_group_node_t));

    p_wb_group_node->group_id = p_group_node->group_id;
    p_wb_group_node->chan_id = p_group_node->chan_id;
    p_wb_group_node->shp_bitmap = p_group_node->shp_bitmap;

    if (++wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
        wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_sch_group_node_wb_sync_func(void* array_data, uint32 index, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_sch_group_node_t *p_sch_grp_node = (sys_sch_group_node_t *)array_data;
    sys_wb_qos_queue_sch_group_node_t *p_wb_sch_grp_node;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = (ctc_wb_data_t *)traversal_data->data;

    max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    p_wb_sch_grp_node = (sys_wb_qos_queue_sch_group_node_t *)wb_data->buffer + wb_data->valid_cnt;

    sal_memset(p_wb_sch_grp_node, 0, sizeof(sys_wb_qos_queue_sch_group_node_t));

    p_wb_sch_grp_node->grp_index = p_sch_grp_node->grp_index;
    p_wb_sch_grp_node->chan_valid = p_sch_grp_node->chan_valid;
    p_wb_sch_grp_node->chan_id = p_sch_grp_node->chan_id;
    p_wb_sch_grp_node->parent_id = p_sch_grp_node->parent_id;

    if (++wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
        wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_port_extender_wb_sync_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_extend_que_node_t *p_port_extender = (sys_extend_que_node_t *)bucket_data;
    sys_wb_qos_queue_port_extender_t *p_wb_port_extender;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = (ctc_wb_data_t *)traversal_data->data;
    if(p_port_extender->type == SYS_EXTEND_QUE_TYPE_MCAST)
    {
        return CTC_E_NONE;
    }
    max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    p_wb_port_extender = (sys_wb_qos_queue_port_extender_t *)wb_data->buffer + wb_data->valid_cnt;

    p_wb_port_extender->lchip = p_port_extender->lchip;
    p_wb_port_extender->lport = p_port_extender->lport;
    p_wb_port_extender->dir = p_port_extender->dir;
    p_wb_port_extender->channel = p_port_extender->channel;
    p_wb_port_extender->type = p_port_extender->type;
    p_wb_port_extender->logic_src_port = p_port_extender->logic_src_port;
    p_wb_port_extender->service_id = p_port_extender->service_id;
    p_wb_port_extender->group_id = p_port_extender->group_id;
    p_wb_port_extender->key_index = p_port_extender->key_index;
    p_wb_port_extender->logic_dst_port = p_port_extender->logic_dst_port;
    p_wb_port_extender->group_is_alloc= p_port_extender->group_is_alloc;
    p_wb_port_extender->nexthop_ptr= p_port_extender->nexthop_ptr;
    p_wb_port_extender->queue_id= p_port_extender->queue_id;
    p_wb_port_extender->rsv3 = 0;
    p_wb_port_extender->rsv2 = 0;
    p_wb_port_extender->rsv1 = 0;

    if (++wb_data->valid_cnt == max_entry_cnt)
    {
        CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
        wb_data->valid_cnt = 0;
    }

    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_logic_src_port_wb_sync_func(void* bucket_data, void* user_data)
{
    uint8  add_flag = 0;
    uint32 max_entry_cnt = 0;
    sys_service_node_t *p_service = (sys_service_node_t *)bucket_data;
    sys_wb_qos_logicsrc_port_t *p_wb_logicsrc_port = NULL;
    sys_qos_logicport_t *p_logic_port_node = NULL;
    ctc_slistnode_t* ctc_slistnode = NULL;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = (ctc_wb_data_t *)traversal_data->data;

    max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    p_wb_logicsrc_port = (sys_wb_qos_logicsrc_port_t *)wb_data->buffer + wb_data->valid_cnt;

    sal_memset(p_wb_logicsrc_port, 0, sizeof(sys_wb_qos_logicsrc_port_t));
    p_wb_logicsrc_port->service_id = p_service->service_id;
    CTC_SLIST_LOOP(p_service->p_logic_port_list, ctc_slistnode)
    {
        p_wb_logicsrc_port = (sys_wb_qos_logicsrc_port_t *)wb_data->buffer + wb_data->valid_cnt;
        p_logic_port_node = _ctc_container_of(ctc_slistnode, sys_qos_logicport_t, head);
        p_wb_logicsrc_port->logic_src_port = p_logic_port_node->logic_port;
        add_flag = 1;

        if (++wb_data->valid_cnt == max_entry_cnt)
        {
            CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
            wb_data->valid_cnt = 0;
        }
    }

    if(add_flag == 0)
    {
        wb_data->valid_cnt = 1;
    }
    return CTC_E_NONE;
}

STATIC int32
_sys_usw_queue_dest_port_wb_sync_func(void* bucket_data, void* user_data)
{
    uint32 max_entry_cnt = 0;
    sys_service_node_t *p_service = (sys_service_node_t *)bucket_data;
    sys_wb_qos_destport_t *p_wb_destport = NULL;
    sys_qos_destport_t *p_destport_node = NULL;
    ctc_slistnode_t* ctc_slistnode = NULL;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    ctc_wb_data_t *wb_data = (ctc_wb_data_t *)traversal_data->data;

    max_entry_cnt = wb_data->buffer_len / (wb_data->key_len + wb_data->data_len);

    p_wb_destport = (sys_wb_qos_destport_t *)wb_data->buffer + wb_data->valid_cnt;

    sal_memset(p_wb_destport, 0, sizeof(sys_wb_qos_destport_t));

    CTC_SLIST_LOOP(p_service->p_dest_port_list, ctc_slistnode)
    {
        p_wb_destport = (sys_wb_qos_destport_t *)wb_data->buffer + wb_data->valid_cnt;
        p_destport_node = _ctc_container_of(ctc_slistnode, sys_qos_destport_t, head);
        p_wb_destport->lport = p_destport_node->lport;
        p_wb_destport->service_id = p_service->service_id;

        if (++wb_data->valid_cnt == max_entry_cnt)
        {
            CTC_ERROR_RETURN(ctc_wb_add_entry(wb_data));
            wb_data->valid_cnt = 0;
        }
    }

    return CTC_E_NONE;
}

int32
sys_usw_queue_wb_sync(uint8 lchip,uint32 app_id, ctc_wb_data_t *p_wb_data)
{
    int32 ret = CTC_E_NONE;
    sys_traverse_t user_data;
    uint32 max_entry_cnt = 0;
    sys_wb_qos_queue_master_t *p_wb_qos_queue_master;
    sys_wb_qos_queue_fc_profile_t *p_wb_queue_fc_profile;
    sys_wb_qos_queue_pfc_profile_t *p_wb_queue_pfc_profile;
    sys_wb_qos_queue_oobfc_profile_t *p_wb_queue_oobfc_profile;
    sys_wb_qos_queue_fc_profile_t *p_wb_queue_fc_dropthrd_profile;
    sys_wb_qos_queue_pfc_profile_t *p_wb_queue_pfc_dropthrd_profile;
    sys_wb_qos_cpu_reason_t *p_wb_cpu_reason;
    sys_wb_qos_queue_fcdl_t *p_wb_queue_fcdl;
    int32 i;
    int32 j;
    uint16 max_num = 0;


    user_data.data = p_wb_data;
    user_data.value1 = lchip;
    user_data.value2 = 0;

    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER)
    {
        /* queue matser */
        CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_master_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER);

        p_wb_qos_queue_master = (sys_wb_qos_queue_master_t *)p_wb_data->buffer;
        p_wb_qos_queue_master->lchip = lchip;
        p_wb_qos_queue_master->store_chan_shp_en = p_usw_queue_master[lchip]->store_chan_shp_en;
        p_wb_qos_queue_master->store_que_shp_en = p_usw_queue_master[lchip]->store_que_shp_en;
        p_wb_qos_queue_master->monitor_drop_en = p_usw_queue_master[lchip]->monitor_drop_en;
        p_wb_qos_queue_master->shp_pps_en = p_usw_queue_master[lchip]->shp_pps_en;
        p_wb_qos_queue_master->net_shp_pps_en = p_usw_queue_master[lchip]->net_shp_pps_en;
        p_wb_qos_queue_master->rsv = 0;
        for(i = 0; i < MCHIP_CAP(SYS_CAP_CHANID_MAX); i++)
        {
            p_wb_qos_queue_master->group_bmp_ets[i] = p_usw_queue_master[lchip]->group_id_ets[i].group_bmp;
            p_wb_qos_queue_master->group_id_ets[i] = p_usw_queue_master[lchip]->group_id_ets[i].group_id;
            p_wb_qos_queue_master->l3_group_id[i] = p_usw_queue_master[lchip]->l3_group_id_bpe[i];
        }
        p_wb_qos_queue_master->oobfc_port_offset = p_usw_queue_master[lchip]->oobfc_group_info.port_offset;
        p_wb_qos_queue_master->oobfc_port_num = p_usw_queue_master[lchip]->oobfc_group_info.port_num;
        p_wb_qos_queue_master->oobfc_port_base = p_usw_queue_master[lchip]->oobfc_group_info.port_base;
        p_wb_qos_queue_master->oobfc_group_num = p_usw_queue_master[lchip]->oobfc_group_info.group_num;
        sal_memcpy(p_wb_qos_queue_master->oobfc_id_bmp, p_usw_queue_master[lchip]->oobfc_group_info.fcid_bmp, sizeof(p_usw_queue_master[lchip]->oobfc_group_info.fcid_bmp));
        p_wb_qos_queue_master->fcdl_action = p_usw_queue_master[lchip]->fcdl_action;

        p_wb_data->valid_cnt = 1;
        CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER);
    }
    
    if(!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_FC_PROFILE)
        {
            /* queue fc profile */
            CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_fc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_PROFILE);
    
            max_entry_cnt = p_wb_data->buffer_len / (p_wb_data->key_len + p_wb_data->data_len);
    
            for (i = 0; i < MCHIP_CAP(SYS_CAP_CHANID_MAX); i++)
            {
                if (NULL == p_usw_queue_master[lchip]->p_fc_profile[i])
                {
                    continue;
                }
    
                if (!DRV_FROM_TMM(lchip) && ctc_spool_is_static(p_usw_queue_master[lchip]->p_fc_profile_pool, p_usw_queue_master[lchip]->p_fc_profile[i]))
                {
                    continue;
                }
    
                p_wb_queue_fc_profile = (sys_wb_qos_queue_fc_profile_t *)p_wb_data->buffer + p_wb_data->valid_cnt;
    
                sal_memset(p_wb_queue_fc_profile, 0, sizeof(sys_wb_qos_queue_fc_profile_t));
    
                p_wb_queue_fc_profile->chan_id = i;
                if(DRV_FROM_AT(lchip))
                {
                     p_wb_queue_fc_profile->xoff = p_usw_queue_master[lchip]->p_fc_profile[i]->xoff;
                     p_wb_queue_fc_profile->xon = p_usw_queue_master[lchip]->p_fc_profile[i]->xon;
                }
                else
                {
                    p_wb_queue_fc_profile->fc_profile_id = p_usw_queue_master[lchip]->p_fc_profile[i]->profile_id;
                }
    
                p_wb_data->valid_cnt++;
                if (p_wb_data->valid_cnt >= max_entry_cnt)
                {
                    CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                    p_wb_data->valid_cnt = 0;
                }
            }
    
            if (p_wb_data->valid_cnt > 0)
            {
                CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                p_wb_data->valid_cnt = 0;
            }
            CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_PROFILE);
       }
       if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_PROFILE)
       {
            /* queue pfc profile */
            CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_pfc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_PROFILE);
    
            max_entry_cnt = p_wb_data->buffer_len / (p_wb_data->key_len + p_wb_data->data_len);
            for (i = 0; i < MCHIP_CAP(SYS_CAP_CHANID_MAX); i++)
            {
                for (j = 0; j < 8; j++)
                {
                    if (NULL == p_usw_queue_master[lchip]->p_pfc_profile[i][j])
                    {
                        continue;
                    }
    
                    if (!DRV_FROM_TMM(lchip) && ctc_spool_is_static(p_usw_queue_master[lchip]->p_pfc_profile_pool, p_usw_queue_master[lchip]->p_pfc_profile[i][j]))
                    {
                        continue;
                    }
    
                    p_wb_queue_pfc_profile = (sys_wb_qos_queue_pfc_profile_t *)p_wb_data->buffer + p_wb_data->valid_cnt;
    
                    sal_memset(p_wb_queue_pfc_profile, 0, sizeof(sys_wb_qos_queue_pfc_profile_t));
    
                    p_wb_queue_pfc_profile->chan_id = i;
                    p_wb_queue_pfc_profile->priority_class = j;
                    if(DRV_FROM_AT(lchip))
                    {
                        p_wb_queue_pfc_profile->xoff = p_usw_queue_master[lchip]->p_pfc_profile[i][j]->xoff;
                        p_wb_queue_pfc_profile->xon = p_usw_queue_master[lchip]->p_pfc_profile[i][j]->xon;
                    }
                    else
                    {
                        p_wb_queue_pfc_profile->pfc_profile_id = p_usw_queue_master[lchip]->p_pfc_profile[i][j]->profile_id;
                    }
                    p_wb_data->valid_cnt++;
                    if (p_wb_data->valid_cnt >= max_entry_cnt)
                    {
                        CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                        p_wb_data->valid_cnt = 0;
                    }
                }
    
            }
    
            if (p_wb_data->valid_cnt > 0)
            {
                CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                p_wb_data->valid_cnt = 0;
            }
            CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_PROFILE);
        }
    }
    
    if (!DRV_FROM_TMM(lchip))
    {
        if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE)
        {

            /* queue group node */
            CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_group_node_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE);

            CTC_ERROR_GOTO(ctc_vector_traverse2(p_usw_queue_master[lchip]->group_vec, 0, _sys_usw_queue_group_node_wb_sync_func, (void *)&user_data), ret, done);
            if (p_wb_data->valid_cnt > 0)
            {
                CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                p_wb_data->valid_cnt = 0;
            }
            CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE);

        }
        
        if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_FC_DROPTH_PROFILE)
        {
        /* queue dropth fc profile */
        CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_fc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_DROPTH_PROFILE);

        max_entry_cnt =  p_wb_data->buffer_len / (p_wb_data->key_len + p_wb_data->data_len);


        for (i = 0; i < MCHIP_CAP(SYS_CAP_CHANID_MAX); i++)
        {
            if (NULL == p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i])
            {
                continue;
            }

            p_wb_queue_fc_dropthrd_profile = (sys_wb_qos_queue_fc_profile_t *)p_wb_data->buffer + p_wb_data->valid_cnt;

            sal_memset(p_wb_queue_fc_dropthrd_profile, 0, sizeof(sys_wb_qos_queue_fc_profile_t));

            p_wb_queue_fc_dropthrd_profile->chan_id = i;
            p_wb_queue_fc_dropthrd_profile->fc_profile_id = p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i]->profile_id;

            p_wb_data->valid_cnt++;
            if (p_wb_data->valid_cnt >= max_entry_cnt)
            {
                CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                p_wb_data->valid_cnt = 0;
            }
        }

        if (p_wb_data->valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
            p_wb_data->valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_DROPTH_PROFILE);
        }
        if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_DROPTH_PROFILE)
        {
        /* queue droth pfc profile */
        CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_pfc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_DROPTH_PROFILE);

        max_entry_cnt = p_wb_data->buffer_len / (p_wb_data->key_len + p_wb_data->data_len);

        for (i = 0; i < MCHIP_CAP(SYS_CAP_CHANID_MAX); i++)
        {
            for (j = 0; j < 8; j++)
            {
                if (NULL == p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j])
                {
                    continue;
                }

                p_wb_queue_pfc_dropthrd_profile = (sys_wb_qos_queue_pfc_profile_t *)p_wb_data->buffer + p_wb_data->valid_cnt;

                sal_memset(p_wb_queue_pfc_dropthrd_profile, 0, sizeof(sys_wb_qos_queue_pfc_profile_t));

                p_wb_queue_pfc_dropthrd_profile->chan_id = i;
                p_wb_queue_pfc_dropthrd_profile->priority_class = j;
                p_wb_queue_pfc_dropthrd_profile->pfc_profile_id = p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j]->profile_id;

                p_wb_data->valid_cnt++;
                if (p_wb_data->valid_cnt >= max_entry_cnt)
                {
                    CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                    p_wb_data->valid_cnt = 0;
                }
            }
        }

        if (p_wb_data->valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
            p_wb_data->valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_DROPTH_PROFILE);
        }

        if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_OOBFC_PROFILE)
        {
        /* egerss oobfc profile */
        CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_oobfc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_OOBFC_PROFILE);

        max_entry_cnt = p_wb_data->buffer_len / (p_wb_data->key_len + p_wb_data->data_len);

        for (i = 0; i < MCHIP_CAP(SYS_CAP_CHANID_MAX); i++)
        {
            if (NULL == p_usw_queue_master[lchip]->p_oobfc_profile[i])
            {
                continue;
            }

            if (ctc_spool_is_static(p_usw_queue_master[lchip]->p_oobfc_profile_pool, p_usw_queue_master[lchip]->p_oobfc_profile[i]))
            {
                continue;
            }

            p_wb_queue_oobfc_profile = (sys_wb_qos_queue_oobfc_profile_t *)p_wb_data->buffer + p_wb_data->valid_cnt;

            sal_memset(p_wb_queue_oobfc_profile, 0, sizeof(sys_wb_qos_queue_oobfc_profile_t));

            p_wb_queue_oobfc_profile->chan_id = i;
            p_wb_queue_oobfc_profile->profile_id = p_usw_queue_master[lchip]->p_oobfc_profile[i]->index.index;

            p_wb_data->valid_cnt++;
            if (p_wb_data->valid_cnt >= max_entry_cnt)
            {
                CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                p_wb_data->valid_cnt = 0;
            }
        }

        if (p_wb_data->valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
            p_wb_data->valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_OOBFC_PROFILE);
        }

    }

    if(!DRV_FROM_AT(lchip))
    {
        if ((app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER) && p_usw_queue_master[lchip]->p_port_extender_hash)
        {
                /* queue port extender */
                CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_port_extender_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER);

                CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_queue_master[lchip]->p_port_extender_hash,
                                                 _sys_usw_queue_port_extender_wb_sync_func, (void *)&user_data), ret, done);
                if (p_wb_data->valid_cnt > 0)
                {
                    CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                    p_wb_data->valid_cnt = 0;
                }
                CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER);
        }
        if ((app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT) && p_usw_queue_master[lchip]->p_service_hash)
        {
                /* service logic src port */
                CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_logicsrc_port_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT);

                CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_queue_master[lchip]->p_service_hash,
                                                 _sys_usw_queue_logic_src_port_wb_sync_func, (void *)&user_data), ret, done);
                if (p_wb_data->valid_cnt > 0)
                {
                    CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                    p_wb_data->valid_cnt = 0;
                }
                CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT);
        }
        if ((app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_DESTPORT) && p_usw_queue_master[lchip]->p_service_hash)
        {
                /* service dst port */
                CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_destport_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_DESTPORT);

                CTC_ERROR_GOTO(ctc_hash_traverse(p_usw_queue_master[lchip]->p_service_hash,
                                                 _sys_usw_queue_dest_port_wb_sync_func, (void *)&user_data), ret, done);
                if (p_wb_data->valid_cnt > 0)
                {
                    CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
                    p_wb_data->valid_cnt = 0;
                }
                CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_DESTPORT);
        }
    }
    if (app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_CPU_REASON)
    {
    /* cpu reason */
    CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_cpu_reason_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_CPU_REASON);

    max_entry_cnt = p_wb_data->buffer_len / (p_wb_data->key_len + p_wb_data->data_len);
    max_num = CTC_PKT_CPU_REASON_MAX_COUNT;
    for (i = 0; i < max_num; i++)
    {
        p_wb_cpu_reason = (sys_wb_qos_cpu_reason_t *)p_wb_data->buffer + p_wb_data->valid_cnt;

        sal_memset(p_wb_cpu_reason, 0, sizeof(sys_wb_qos_cpu_reason_t));

        p_wb_cpu_reason->reason_id = i;
        p_wb_cpu_reason->dest_type = p_usw_queue_master[lchip]->cpu_reason[i].dest_type;
        p_wb_cpu_reason->user_define_mode0 = p_usw_queue_master[lchip]->cpu_reason[i].user_define_mode[CTC_INGRESS];
        p_wb_cpu_reason->user_define_mode1 = p_usw_queue_master[lchip]->cpu_reason[i].user_define_mode[CTC_EGRESS];
        p_wb_cpu_reason->excp_id0 = p_usw_queue_master[lchip]->cpu_reason[i].excp_id[CTC_INGRESS];
        p_wb_cpu_reason->excp_id1 = p_usw_queue_master[lchip]->cpu_reason[i].excp_id[CTC_EGRESS];
        p_wb_cpu_reason->nh_id = p_usw_queue_master[lchip]->cpu_reason[i].nh_id;
        p_wb_cpu_reason->sub_queue_id = p_usw_queue_master[lchip]->cpu_reason[i].sub_queue_id;
        p_wb_cpu_reason->dest_port = p_usw_queue_master[lchip]->cpu_reason[i].dest_port;
        p_wb_cpu_reason->dir = p_usw_queue_master[lchip]->cpu_reason[i].dir;
        p_wb_cpu_reason->policer_id[0] = p_usw_queue_master[lchip]->cpu_reason[i].policer_id[0];
        p_wb_cpu_reason->policer_id[1] = p_usw_queue_master[lchip]->cpu_reason[i].policer_id[1];
        p_wb_cpu_reason->tcat_prof_id = p_usw_queue_master[lchip]->cpu_reason[i].tcat_prof_id;
        p_wb_cpu_reason->raw_dest_en = p_usw_queue_master[lchip]->cpu_reason[i].raw_dest_en;
        p_wb_cpu_reason->sub_index = p_usw_queue_master[lchip]->cpu_reason[i].sub_idx;

        p_wb_data->valid_cnt++;
        if (p_wb_data->valid_cnt >= max_entry_cnt)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
            p_wb_data->valid_cnt = 0;
        }
    }

    if (p_wb_data->valid_cnt > 0)
    {
        CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
        p_wb_data->valid_cnt = 0;
    }
    CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_CPU_REASON);
    }
    if ((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        if(app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_SCH_GROUP_NODE)
        {
         /* queue sch group node */
        CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_sch_group_node_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_SCH_GROUP_NODE);

        CTC_ERROR_GOTO(ctc_vector_traverse2(p_usw_queue_master[lchip]->sch_group_vec, 0, _sys_usw_queue_sch_group_node_wb_sync_func, (void *)&user_data), ret, done);
        if (p_wb_data->valid_cnt > 0)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
            p_wb_data->valid_cnt = 0;
        }
        CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_SCH_GROUP_NODE);
        }
    }

    if(app_id == 0 || CTC_WB_SUBID(app_id) == SYS_WB_APPID_QOS_SUBID_QUEUE_FCDL)
    {
     /* queue sch group node */
    CTC_WB_INIT_DATA_T(p_wb_data, sys_wb_qos_queue_fcdl_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FCDL);
    max_entry_cnt = p_wb_data->buffer_len / (p_wb_data->key_len + p_wb_data->data_len);
    for (i = 0; i < MCHIP_CAP(SYS_CAP_PORT_NUM_PER_CHIP); i++)
    {
        p_wb_queue_fcdl = (sys_wb_qos_queue_fcdl_t *)p_wb_data->buffer + p_wb_data->valid_cnt;
    
        sal_memset(p_wb_queue_fcdl, 0, sizeof(sys_wb_qos_queue_fcdl_t));
    
        p_wb_queue_fcdl->lport = i;
        p_wb_queue_fcdl->mode = p_usw_queue_master[lchip]->fcdl_info[i].mode;
        p_wb_queue_fcdl->timeout = p_usw_queue_master[lchip]->fcdl_info[i].timeout;

        p_wb_data->valid_cnt++;
        if (p_wb_data->valid_cnt >= max_entry_cnt)
        {
            CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
            p_wb_data->valid_cnt = 0;
        }
    }

    if (p_wb_data->valid_cnt > 0)
    {
        CTC_ERROR_GOTO(ctc_wb_add_entry(p_wb_data), ret, done);
        p_wb_data->valid_cnt = 0;
    }
    CTC_WB_SYNC_END_DATA(CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FCDL);
    }
done:
    return ret;
}

STATIC int32
_sys_usw_queue_queue_node_wb_restore_func(void* array_data, void* user_data)
{
    sys_queue_node_t *p_queue_node = (sys_queue_node_t *)array_data;
    sys_traverse_t *traversal_data = (sys_traverse_t *)user_data;
    sys_queue_shp_profile_t queue_shp_profile = {0};
    sys_queue_shp_profile_t *p_queue_shp_profile_get = NULL;
    sys_queue_meter_profile_t queue_meter_profile = {0};
    sys_queue_meter_profile_t *p_queue_meter_profile_get = NULL;
    sys_queue_drop_profile_t queue_drop_profile[SYS_QUEUE_SUB_NODE_NUM];
    sys_queue_drop_wtd_profile_t queue_drop_wtd_profile = {0};
    sys_queue_drop_wtd_profile_t *p_queue_drop_wtd_profile_get = NULL;
    sys_queue_drop_wred_profile_t queue_drop_wred_profile[SYS_QUEUE_SUB_NODE_NUM];
    sys_queue_drop_wred_profile_t *p_queue_drop_wred_profile_get = NULL;
    sys_queue_guarantee_t queue_guaran_profile = {0};
    sys_queue_guarantee_t *p_queue_guaran_profile_get = NULL;
    uint8 lchip = traversal_data->value1;
    uint8 hw_valid = 0;
    uint8 queue_type = 0;
    uint8 ofst = 0;
    uint8 loop_num = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 stats_offet = 0;
    ds1_t ds;

    if(!DRV_FROM_TMM(lchip))
    {
        sal_memset(&queue_shp_profile, 0 ,sizeof(queue_shp_profile));
        sal_memset(&ds, 0 , sizeof(ds));
        CTC_ERROR_RETURN(sys_usw_queue_get_queue_type_by_queue_id(lchip, p_queue_node->queue_id,&queue_type));
        queue_shp_profile.queue_type = queue_type;
        CTC_ERROR_RETURN(_sys_usw_queue_shp_get_queue_shape_from_asic(lchip, p_queue_node, &queue_shp_profile));

        if (queue_shp_profile.profile_id)
        {        
            /*old profille*/
            queue_shp_profile.lchip = lchip;
            queue_shp_profile.p_ds = &ds;
            CTC_ERROR_RETURN(_sys_usw_queue_shp_get_queue_shape_profile_from_asic(lchip, &queue_shp_profile));

            CTC_ERROR_RETURN(ctc_spool_add(p_usw_queue_master[lchip]->p_queue_profile_pool,
                                         &queue_shp_profile,
                                         NULL,
                                         &p_queue_shp_profile_get));

            p_queue_node->shp_profile_id = p_queue_shp_profile_get->profile_id;

            p_queue_node->shp_en = 1;
            p_queue_node->type = queue_shp_profile.queue_type;
        }
        else
        {
            p_queue_node->shp_en = 0;
        }

        sal_memset(&queue_meter_profile, 0 ,sizeof(queue_meter_profile));
        CTC_ERROR_RETURN(_sys_usw_queue_shp_get_queue_meter_from_asic(lchip, p_queue_node, &queue_meter_profile));
        if (queue_meter_profile.profile_id)
        {
            /*old profille*/
            queue_meter_profile.lchip = lchip;
            queue_meter_profile.p_ds = &ds;
            CTC_ERROR_RETURN(_sys_usw_queue_shp_get_queue_meter_profile_from_asic(lchip, &queue_meter_profile));

            CTC_ERROR_RETURN(ctc_spool_add(p_usw_queue_master[lchip]->p_queue_meter_profile_pool,
                                         &queue_meter_profile,
                                         NULL,
                                         &p_queue_meter_profile_get));

            p_queue_node->meter_profile_id = p_queue_meter_profile_get->profile_id;
        }



        sal_memset(&queue_drop_wtd_profile, 0, sizeof(queue_drop_wtd_profile));
        sal_memset(queue_drop_profile, 0, sizeof(sys_queue_drop_profile_t) * SYS_QUEUE_SUB_NODE_NUM);
        sal_memset(&ds, 0 , sizeof(ds));
        queue_drop_wtd_profile.p_ds = &ds;
        queue_drop_profile[0].p_drop_wtd_profile = &queue_drop_wtd_profile;
        hw_valid = 0;
        CTC_ERROR_RETURN(_sys_usw_queue_drop_read_asic(lchip, 0, p_queue_node, &queue_drop_profile[0], &hw_valid));
        if (queue_drop_wtd_profile.profile_id && queue_drop_wtd_profile.profile_id != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WTD_PROFILE_NUM) && hw_valid)
        {
            CTC_ERROR_RETURN(_sys_usw_queue_drop_read_profile_from_asic(lchip, 0, p_queue_node, &queue_drop_profile[0]));

            CTC_ERROR_RETURN(_sys_usw_queue_drop_wtd_profile_add_spool(lchip, NULL,
                                                                     &queue_drop_wtd_profile, &p_queue_drop_wtd_profile_get));

            p_queue_node->drop_wtd_profile_id = p_queue_drop_wtd_profile_get->profile_id;
        }

        /*read profile id from asic*/
        cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_queueGuaranteedThrdProfId_f);
        DRV_FIELD_IOCTL(lchip, p_queue_node->queue_id, cmd, &value);
        queue_guaran_profile.profile_id = value;
        if (queue_guaran_profile.profile_id && queue_guaran_profile.profile_id != 0x7) /*profile_id = 0x7 indicate disable*/
        {
            DsErmQueueGuaranteedThrdProfile_m ds_profile;
            cmd = DRV_IOR(DsErmQueueGuaranteedThrdProfile_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, queue_guaran_profile.profile_id, cmd, &ds_profile));
            queue_guaran_profile.p_ds = &ds_profile;
            CTC_ERROR_RETURN(_sys_usw_qos_guarantee_profile_add_spool(lchip, NULL,
                                                                    &queue_guaran_profile, &p_queue_guaran_profile_get));

            p_queue_node->guarantee_profile_id = p_queue_guaran_profile_get->profile_id;
        }

    }

    sal_memset(&queue_drop_wred_profile, 0, sizeof(sys_queue_drop_wred_profile_t) * SYS_QUEUE_SUB_NODE_NUM);
    sal_memset(queue_drop_profile, 0, sizeof(sys_queue_drop_profile_t) * SYS_QUEUE_SUB_NODE_NUM);
    sal_memset(&ds, 0 , sizeof(ds));
    queue_drop_wred_profile[0].p_ds = &ds;
    queue_drop_wred_profile[0].lchip = lchip;
    queue_drop_profile[0].p_drop_wred_profile = &queue_drop_wred_profile[0];
    queue_drop_wred_profile[1].p_ds = &ds;
    queue_drop_wred_profile[1].lchip = lchip;
    queue_drop_profile[1].p_drop_wred_profile = &queue_drop_wred_profile[1];

    /* TMM get 1 profile, AT get 2 profiles */
    CTC_ERROR_RETURN(_sys_usw_queue_drop_read_asic(lchip, 1, p_queue_node, queue_drop_profile, &hw_valid));

    loop_num = DRV_FROM_AT(lchip) ? SYS_QUEUE_SUB_NODE_NUM : 1;
    for (ofst = 0; ofst < loop_num; ofst++)
    {
        hw_valid = 0;
        if(((DRV_FROM_TMM(lchip) && queue_drop_wred_profile[ofst].profile_id)
            || (!DRV_FROM_TMM(lchip) && queue_drop_wred_profile[ofst].profile_id != MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM))) && hw_valid)
        {
            CTC_ERROR_RETURN(_sys_usw_queue_drop_read_profile_from_asic(lchip, 1, p_queue_node, &queue_drop_profile[ofst]));

            CTC_ERROR_RETURN(_sys_usw_queue_drop_wred_profile_add_spool(lchip, NULL,
                                                                        &queue_drop_wred_profile[ofst], &p_queue_drop_wred_profile_get));

            p_queue_node->node[ofst].drop_wred_profile_id = p_queue_drop_wred_profile_get->profile_id;
        }
    }

    if (DRV_IS_TSINGMA(lchip) && SYS_IS_EXT_QUEUE(p_queue_node->queue_id))
    {
        cmd = DRV_IOR(DsErmQueueCfg_t, DsErmQueueCfg_statsPtr_f);
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, p_queue_node->queue_id, cmd, &stats_offet));
        if(stats_offet != 0)
        {
            CTC_ERROR_RETURN(sys_usw_flow_stats_restore_statsptr( lchip, 2, CTC_INGRESS, SYS_STATS_TYPE_QUEUE, stats_offet));
        }
    }
    return CTC_E_NONE;
}

int32
sys_usw_queue_wb_restore(uint8 lchip, ctc_wb_query_t *p_wb_query)
{
    int32 ret = CTC_E_NONE;
    uint32 entry_cnt = 0;
    sys_usw_opf_t opf;
    sys_wb_qos_queue_master_t *p_wb_qos_queue_master;
    sys_wb_qos_queue_group_node_t *p_wb_qos_queue_group_node;
    sys_wb_qos_queue_group_node_t wb_qos_queue_group_node;
    sys_queue_group_node_t *p_queue_group_node;
    sys_wb_qos_queue_sch_group_node_t *p_wb_qos_queue_sch_group_node;
    sys_wb_qos_queue_sch_group_node_t wb_qos_queue_sch_group_node;
    sys_sch_group_node_t *p_sch_group_node;
    sys_sch_group_node_t *p_sch_group_parent_node;
    sys_sch_group_child_node_t *p_sch_group_child;
    sys_group_shp_profile_t group_shp_profile;
    sys_group_shp_profile_t *p_group_shp_profile_get;
    sys_group_meter_profile_t group_meter_profile;
    sys_group_meter_profile_t *p_group_meter_profile_get;
    sys_wb_qos_queue_fc_profile_t *p_wb_queue_fc_profile;
    sys_wb_qos_queue_fc_profile_t wb_queue_fc_profile;
    sys_wb_qos_queue_oobfc_profile_t *p_wb_queue_oobfc_profile;
    sys_wb_qos_queue_oobfc_profile_t wb_queue_oobfc_profile;
    sys_qos_oobfc_profile_t queue_oobfc_profile;
    sys_qos_oobfc_profile_t *p_queue_oobfc_profile_get;
    sys_qos_fc_profile_t queue_fc_profile;
    sys_qos_fc_profile_t *p_queue_fc_profile_get;
    sys_wb_qos_queue_pfc_profile_t *p_wb_queue_pfc_profile;
    sys_wb_qos_queue_pfc_profile_t wb_queue_pfc_profile;
    sys_qos_fc_profile_t queue_pfc_profile;
    sys_qos_fc_profile_t *p_queue_pfc_profile_get;
    sys_wb_qos_queue_port_extender_t *p_wb_port_extender;
    sys_wb_qos_queue_port_extender_t wb_port_extender;
    sys_wb_qos_logicsrc_port_t *p_wb_logicsrc_port;
    sys_wb_qos_logicsrc_port_t wb_logicsrc_port;
    sys_wb_qos_destport_t *p_wb_dest_port;
    sys_wb_qos_destport_t wb_dest_port;
    sys_qos_logicport_t *p_logicsrc_port = NULL;
    sys_qos_destport_t *p_dest_port = NULL;
    sys_extend_que_node_t *p_port_extender;
    sys_qos_logicport_service_t *p_logicport_service;
    sys_service_node_t *p_service;
    sys_service_node_t service;
    sys_wb_qos_cpu_reason_t *p_wb_cpu_reason;
    sys_wb_qos_cpu_reason_t wb_cpu_reason;
    sys_wb_qos_queue_fcdl_t *p_wb_queue_fcdl;
    sys_wb_qos_queue_fcdl_t wb_queue_fcdl;
    sys_cpu_reason_dest_info_t dest_info;
    sys_wb_qos_queue_fc_profile_t *p_wb_queue_fc_dropthrd_profile;
    sys_wb_qos_queue_fc_profile_t wb_queue_fc_dropthrd_profile;
    sys_qos_fc_profile_t queue_fc_dropthrd_profile;
    sys_qos_fc_profile_t *p_queue_fc_dropthrd_profile_get;
    sys_wb_qos_queue_pfc_profile_t *p_wb_queue_pfc_dropthrd_profile;
    sys_wb_qos_queue_pfc_profile_t wb_queue_pfc_dropthrd_profile;
    sys_qos_fc_profile_t queue_pfc_dropthrd_profile;
    sys_qos_fc_profile_t *p_queue_pfc_dropthrd_profile_get;
    sys_traverse_t user_data;
    uint8 opf_num = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    uint16 i = 0;

    user_data.value1 = lchip;
    MALLOC_ZERO(MEM_QUEUE_MODULE, p_wb_qos_queue_master, sizeof(sys_wb_qos_queue_master_t));
    CTC_ERROR_RETURN(NULL == p_wb_qos_queue_master ? CTC_E_NO_MEMORY: CTC_E_NONE);

    /* queue master */
    CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_master_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_MASTER);

    CTC_ERROR_GOTO(ctc_wb_query_entry(p_wb_query), ret, done);

    if (p_wb_query->valid_cnt != 1 || p_wb_query->is_end != 1)
    {
        CTC_WB_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "query qos queue master error! valid_cnt: %d, is_end: %d.\n", p_wb_query->valid_cnt, p_wb_query->is_end);
        goto done;
    }

    sal_memcpy((uint8 *)p_wb_qos_queue_master, (uint8 *)p_wb_query->buffer, (p_wb_query->key_len + p_wb_query->data_len));

    p_usw_queue_master[lchip]->store_chan_shp_en = p_wb_qos_queue_master->store_chan_shp_en;
    p_usw_queue_master[lchip]->store_que_shp_en = p_wb_qos_queue_master->store_que_shp_en;
    p_usw_queue_master[lchip]->monitor_drop_en = p_wb_qos_queue_master->monitor_drop_en;
    p_usw_queue_master[lchip]->shp_pps_en = p_wb_qos_queue_master->shp_pps_en;
    p_usw_queue_master[lchip]->net_shp_pps_en = p_wb_qos_queue_master->net_shp_pps_en;
    if((DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
    for (i = 0; i < MCHIP_CAP(SYS_CAP_CHANID_MAX); i++)
    {
        p_usw_queue_master[lchip]->group_id_ets[i].group_bmp = p_wb_qos_queue_master->group_bmp_ets[i];
        p_usw_queue_master[lchip]->group_id_ets[i].group_id = p_wb_qos_queue_master->group_id_ets[i];
        p_usw_queue_master[lchip]->l3_group_id_bpe[i] = p_wb_qos_queue_master->l3_group_id[i];
        if(p_usw_queue_master[lchip]->group_id_ets[i].group_id != INVALID_QUEUE_GROUP_ID_ETS)
        {
            CTC_ERROR_GOTO(_sys_usw_queue_alloc_ext_group_from_position(lchip, 3, p_usw_queue_master[lchip]->group_id_ets[i].group_id), ret, done);
        }
    }
    }
    cmd = DRV_IOR(QMgrOobFcCtl_t, QMgrOobFcCtl_oobFcGrpIdBase_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    p_usw_queue_master[lchip]->oobfc_group_info.group_base = value;
    p_usw_queue_master[lchip]->oobfc_group_info.group_num = p_wb_qos_queue_master->oobfc_group_num;
    p_usw_queue_master[lchip]->oobfc_group_info.port_num = p_wb_qos_queue_master->oobfc_port_num;
    p_usw_queue_master[lchip]->oobfc_group_info.port_base = p_wb_qos_queue_master->oobfc_port_base;
    p_usw_queue_master[lchip]->oobfc_group_info.port_offset = p_wb_qos_queue_master->oobfc_port_offset;
    sal_memcpy(p_usw_queue_master[lchip]->oobfc_group_info.fcid_bmp, p_wb_qos_queue_master->oobfc_id_bmp, sizeof(p_usw_queue_master[lchip]->oobfc_group_info.fcid_bmp));
    p_usw_queue_master[lchip]->fcdl_action = p_wb_qos_queue_master->fcdl_action;
    cmd = DRV_IOR(ErmMiscCtl_t, ErmMiscCtl_resourceCheckMode_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &value));
    p_usw_queue_master[lchip]->resrc_check_mode = value;

    if(!(DRV_IS_TMM(lchip) || DRV_IS_TMG(lchip)))
    {
        /* queue fc profile */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_fc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_PROFILE);
    
        entry_cnt = 0;
    
        sal_memset(&wb_queue_fc_profile, 0, sizeof(sys_wb_qos_queue_fc_profile_t));
        p_wb_queue_fc_profile = &wb_queue_fc_profile;
    
        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);
    
        sal_memcpy((uint8 *)&wb_queue_fc_profile, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                   (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;
    
        if (p_wb_queue_fc_profile->chan_id >= MCHIP_CAP(SYS_CAP_CHANID_MAX))
        {
            continue;
        }

        if(DRV_FROM_AT(lchip))
        {
            p_queue_fc_profile_get = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_fc_profile_t));
            if(NULL == p_queue_fc_profile_get)
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }
            p_queue_fc_profile_get->xoff = p_wb_queue_fc_profile->xoff;
            p_queue_fc_profile_get->xon = p_wb_queue_fc_profile->xon;
        }
        else
        {
            sal_memset(&queue_fc_profile, 0, sizeof(sys_qos_fc_profile_t));
            queue_fc_profile.profile_id = p_wb_queue_fc_profile->fc_profile_id;
    
            CTC_ERROR_GOTO(sys_usw_qos_fc_get_profile_from_asic(lchip, 0, &queue_fc_profile), ret, done);
    
            CTC_ERROR_GOTO(_sys_usw_qos_fc_profile_add_spool(lchip, 0, 0, p_usw_queue_master[lchip]->p_fc_profile[p_wb_queue_fc_profile->chan_id],
                                                             &queue_fc_profile, &p_queue_fc_profile_get), ret, done);
        }
        p_usw_queue_master[lchip]->p_fc_profile[p_wb_queue_fc_profile->chan_id] = p_queue_fc_profile_get;
    
        CTC_WB_QUERY_ENTRY_END(p_wb_query);
    
        /* queue pfc profile */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_pfc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_PROFILE);
    
        entry_cnt = 0;
    
        sal_memset(&wb_queue_pfc_profile, 0, sizeof(sys_wb_qos_queue_pfc_profile_t));
        p_wb_queue_pfc_profile = &wb_queue_pfc_profile;
    
        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);
    
        sal_memcpy((uint8 *)&wb_queue_pfc_profile, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                   (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;
    
        if ((p_wb_queue_pfc_profile->chan_id >= MCHIP_CAP(SYS_CAP_CHANID_MAX)) || (p_wb_queue_pfc_profile->priority_class >= 8))
        {
            continue;
        }

        if (DRV_FROM_AT(lchip))
        {
            p_queue_pfc_profile_get = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_fc_profile_t));
            if(NULL == p_queue_pfc_profile_get)
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }
            p_queue_pfc_profile_get->xoff = p_wb_queue_pfc_profile->xoff;
            p_queue_pfc_profile_get->xon = p_wb_queue_pfc_profile->xon;
        }
        else
        {
            sal_memset(&queue_pfc_profile, 0, sizeof(sys_qos_fc_profile_t));
            queue_pfc_profile.profile_id = p_wb_queue_pfc_profile->pfc_profile_id;
    
            CTC_ERROR_GOTO(sys_usw_qos_fc_get_profile_from_asic(lchip, 1, &queue_pfc_profile), ret, done);
    
            CTC_ERROR_GOTO(_sys_usw_qos_fc_profile_add_spool(lchip, 1, 0, p_usw_queue_master[lchip]->p_pfc_profile[p_wb_queue_pfc_profile->chan_id][p_wb_queue_pfc_profile->priority_class],
                                                             &queue_pfc_profile, &p_queue_pfc_profile_get), ret, done);
    
        }
        p_usw_queue_master[lchip]->p_pfc_profile[p_wb_queue_pfc_profile->chan_id][p_wb_queue_pfc_profile->priority_class] = p_queue_pfc_profile_get;
    
        CTC_WB_QUERY_ENTRY_END(p_wb_query);
    }
    if (!DRV_FROM_TMM(lchip))
    {
        p_usw_queue_master[lchip]->p_queue_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_queue_shp_restore_profileId;
        p_usw_queue_master[lchip]->p_queue_meter_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_queue_meter_restore_profileId;
    }
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_queue_drop_wred_restore_profileId;

    CTC_ERROR_GOTO(ctc_vector_traverse(p_usw_queue_master[lchip]->queue_vec, _sys_usw_queue_queue_node_wb_restore_func, (void*)&user_data), ret, done);

    if (!DRV_FROM_TMM(lchip))
    {
        p_usw_queue_master[lchip]->p_queue_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_queue_shp_alloc_profileId;
        p_usw_queue_master[lchip]->p_queue_meter_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_queue_meter_alloc_profileId;
    }
    p_usw_queue_master[lchip]->p_drop_wred_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_queue_drop_wred_alloc_profileId;

    if(!DRV_FROM_TMM(lchip))
    {
        /* queue group node */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_group_node_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_GROUP_NODE);

        entry_cnt = 0;

        sal_memset(&wb_qos_queue_group_node, 0, sizeof(sys_wb_qos_queue_group_node_t));
        p_wb_qos_queue_group_node = &wb_qos_queue_group_node;

        p_usw_queue_master[lchip]->p_group_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_group_shp_restore_profileId;
        p_usw_queue_master[lchip]->p_group_profile_meter_pool->spool_alloc = (spool_alloc_fn)_sys_usw_group_meter_restore_profileId;

        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

        sal_memcpy((uint8 *)&wb_qos_queue_group_node, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                   (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;

        p_queue_group_node = ctc_vector_get(p_usw_queue_master[lchip]->group_vec, p_wb_qos_queue_group_node->group_id);
        if (NULL == p_queue_group_node)
        {
            p_queue_group_node = mem_malloc(MEM_QUEUE_MODULE,  sizeof(sys_queue_group_node_t));
            if (NULL == p_queue_group_node)
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }

            sal_memset(p_queue_group_node, 0, sizeof(sys_queue_group_node_t));
            p_queue_group_node->group_id = p_wb_qos_queue_group_node->group_id;
            p_queue_group_node->chan_id = p_wb_qos_queue_group_node->chan_id;
            p_queue_group_node->shp_bitmap = p_wb_qos_queue_group_node->shp_bitmap;

            if (!ctc_vector_add(p_usw_queue_master[lchip]->group_vec,
                                          p_queue_group_node->group_id, p_queue_group_node))
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }
        }
        else
        {
            p_queue_group_node->chan_id = p_wb_qos_queue_group_node->chan_id;
            p_queue_group_node->shp_bitmap = p_wb_qos_queue_group_node->shp_bitmap;
        }

        sal_memset(&group_shp_profile, 0, sizeof(sys_group_shp_profile_t));
        CTC_ERROR_GOTO(_sys_usw_queue_shp_get_group_shape_from_asic(lchip, 1, p_queue_group_node->group_id, &(group_shp_profile.profile_id)), ret, done);
        if (group_shp_profile.profile_id)
        {
            CTC_ERROR_GOTO(_sys_usw_queue_shp_get_group_shape_profile_from_asic(lchip, &group_shp_profile), ret, done);

            CTC_ERROR_GOTO(ctc_spool_add(p_usw_queue_master[lchip]->p_group_profile_pool,
                                         &group_shp_profile,
                                         NULL,
                                         &p_group_shp_profile_get), ret, done);

            p_queue_group_node->p_shp_profile = p_group_shp_profile_get;
        }

        sal_memset(&group_meter_profile, 0, sizeof(sys_group_meter_profile_t));
        CTC_ERROR_GOTO(_sys_usw_queue_shp_get_group_shape_from_asic(lchip, 0, p_queue_group_node->group_id, &(group_meter_profile.profile_id)), ret, done);
        if (group_meter_profile.profile_id)
        {
            CTC_ERROR_GOTO(_sys_usw_queue_shp_get_group_meter_profile_from_asic(lchip, &group_meter_profile), ret, done);

            CTC_ERROR_GOTO(ctc_spool_add(p_usw_queue_master[lchip]->p_group_profile_meter_pool,
                                         &group_meter_profile,
                                         NULL,
                                         &p_group_meter_profile_get), ret, done);

            p_queue_group_node->p_meter_profile = p_group_meter_profile_get;
        }

        CTC_WB_QUERY_ENTRY_END(p_wb_query);

        p_usw_queue_master[lchip]->p_group_profile_pool->spool_alloc = (spool_alloc_fn)_sys_usw_group_shp_alloc_profileId;
        p_usw_queue_master[lchip]->p_group_profile_meter_pool->spool_alloc = (spool_alloc_fn)_sys_usw_group_meter_alloc_profileId;

        

        /* queue dropth fc profile */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_fc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FC_DROPTH_PROFILE);

        entry_cnt = 0;

        sal_memset(&wb_queue_fc_dropthrd_profile, 0, sizeof(sys_wb_qos_queue_fc_profile_t));
        p_wb_queue_fc_dropthrd_profile = &wb_queue_fc_dropthrd_profile;

        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

        sal_memcpy((uint8 *)&wb_queue_fc_dropthrd_profile, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                   (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;

        if (p_wb_queue_fc_dropthrd_profile->chan_id >= MCHIP_CAP(SYS_CAP_CHANID_MAX))
        {
            continue;
        }

        sal_memset(&queue_fc_dropthrd_profile, 0, sizeof(queue_fc_dropthrd_profile));
        queue_fc_dropthrd_profile.profile_id = p_wb_queue_fc_dropthrd_profile->fc_profile_id;

        CTC_ERROR_GOTO(sys_usw_qos_fc_get_dropthrd_profile_from_asic(lchip, 0, &queue_fc_dropthrd_profile), ret, done);

        CTC_ERROR_GOTO(_sys_usw_qos_fc_profile_add_spool(lchip, 0, 1, p_usw_queue_master[lchip]->p_dropthrd_fc_profile[p_wb_queue_fc_dropthrd_profile->chan_id],
                                                         &queue_fc_dropthrd_profile, &p_queue_fc_dropthrd_profile_get), ret, done);

        p_usw_queue_master[lchip]->p_dropthrd_fc_profile[p_wb_queue_fc_dropthrd_profile->chan_id] = p_queue_fc_dropthrd_profile_get;

        CTC_WB_QUERY_ENTRY_END(p_wb_query);

        /* queue dropth pfc profile */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_pfc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PFC_DROPTH_PROFILE);

        entry_cnt = 0;

        sal_memset(&wb_queue_pfc_dropthrd_profile, 0, sizeof(sys_wb_qos_queue_pfc_profile_t));
        p_wb_queue_pfc_dropthrd_profile = &wb_queue_pfc_dropthrd_profile;

        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

        sal_memcpy((uint8 *)&wb_queue_pfc_dropthrd_profile, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                   (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;

        if ((p_wb_queue_pfc_dropthrd_profile->chan_id >= MCHIP_CAP(SYS_CAP_CHANID_MAX)) || (p_wb_queue_pfc_dropthrd_profile->priority_class >= 8))
        {
            continue;
        }

        sal_memset(&queue_pfc_dropthrd_profile, 0, sizeof(sys_qos_fc_profile_t));
        queue_pfc_dropthrd_profile.profile_id = p_wb_queue_pfc_dropthrd_profile->pfc_profile_id;

        CTC_ERROR_GOTO(sys_usw_qos_fc_get_dropthrd_profile_from_asic(lchip, 1, &queue_pfc_dropthrd_profile), ret, done);

        CTC_ERROR_GOTO(_sys_usw_qos_fc_profile_add_spool(lchip, 1, 1, p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[p_wb_queue_pfc_dropthrd_profile->chan_id][p_wb_queue_pfc_dropthrd_profile->priority_class],
                                                         &queue_pfc_dropthrd_profile, &p_queue_pfc_dropthrd_profile_get), ret, done);

        p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[p_wb_queue_pfc_dropthrd_profile->chan_id][p_wb_queue_pfc_dropthrd_profile->priority_class] = p_queue_pfc_dropthrd_profile_get;

        CTC_WB_QUERY_ENTRY_END(p_wb_query);

        /* egress oobfc profile */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_oobfc_profile_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_OOBFC_PROFILE);

        entry_cnt = 0;

        sal_memset(&wb_queue_oobfc_profile, 0, sizeof(sys_wb_qos_queue_oobfc_profile_t));
        p_wb_queue_oobfc_profile = &wb_queue_oobfc_profile;

        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

        sal_memcpy((uint8 *)&wb_queue_oobfc_profile, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                   (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;

        if (p_wb_queue_oobfc_profile->chan_id >= MCHIP_CAP(SYS_CAP_CHANID_MAX))
        {
            continue;
        }

        sal_memset(&queue_oobfc_profile, 0, sizeof(sys_qos_oobfc_profile_t));
        queue_oobfc_profile.index.index = p_wb_queue_oobfc_profile->profile_id;

        CTC_ERROR_GOTO(sys_usw_qos_oobfc_get_profile_from_asic(lchip, &queue_oobfc_profile), ret, done);

        CTC_ERROR_GOTO(_sys_usw_qos_oobfc_profile_add_spool(lchip, p_usw_queue_master[lchip]->p_oobfc_profile[p_wb_queue_oobfc_profile->chan_id],
                                                         &queue_oobfc_profile, &p_queue_oobfc_profile_get), ret, done);

        p_usw_queue_master[lchip]->p_oobfc_profile[p_wb_queue_oobfc_profile->chan_id] = p_queue_oobfc_profile_get;

        CTC_WB_QUERY_ENTRY_END(p_wb_query);


    }

    /* queue port extender */
    if (p_usw_queue_master[lchip]->p_port_extender_hash)
    {
    CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_port_extender_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_PORT_EXTENDER);

    entry_cnt = 0;

    sal_memset(&wb_port_extender, 0, sizeof(sys_wb_qos_queue_port_extender_t));
    p_wb_port_extender = &wb_port_extender;

    CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

    sal_memcpy((uint8 *)&wb_port_extender, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                                        (p_wb_query->key_len + p_wb_query->data_len));
    entry_cnt++;

    p_port_extender = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_extend_que_node_t));
    if (NULL == p_port_extender)
    {
        ret = CTC_E_NO_MEMORY;
        goto done;
    }

    sal_memset(p_port_extender, 0, sizeof(sys_extend_que_node_t));
    p_port_extender->lchip = p_wb_port_extender->lchip;
    p_port_extender->lport = p_wb_port_extender->lport;
    p_port_extender->channel = p_wb_port_extender->channel;
    p_port_extender->dir = p_wb_port_extender->dir;
    p_port_extender->type = p_wb_port_extender->type;
    p_port_extender->service_id = p_wb_port_extender->service_id;
    p_port_extender->group_id = p_wb_port_extender->group_id;
    p_port_extender->key_index = p_wb_port_extender->key_index;
    p_port_extender->logic_dst_port = p_wb_port_extender->logic_dst_port;
    p_port_extender->group_is_alloc= p_wb_port_extender->group_is_alloc;
    p_port_extender->logic_src_port = p_wb_port_extender->logic_src_port;
    p_port_extender->nexthop_ptr = p_wb_port_extender->nexthop_ptr;
    p_port_extender->queue_id = p_wb_port_extender->queue_id;

    ctc_hash_insert(p_usw_queue_master[lchip]->p_port_extender_hash, p_port_extender);
    opf_num = 1;
    if(p_port_extender->type != SYS_EXTEND_QUE_TYPE_LOGIC_PORT && ((p_port_extender->group_is_alloc && p_port_extender->dir == CTC_EGRESS) || (p_port_extender->dir == CTC_INGRESS)))
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
        opf.pool_type = p_usw_queue_master[lchip]->opf_type_group_id;
        opf.pool_index = 0;
        ret = sys_usw_opf_alloc_offset_from_position(lchip, &opf, opf_num, p_port_extender->group_id);
        if (CTC_E_NONE != ret && CTC_E_EXIST != ret)
        {
            goto done;
        }
    }
    if(!DRV_FROM_TMM(lchip))
    {
    sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
    opf.pool_type = p_usw_queue_master[lchip]->opf_type_tcam_index;
    opf.pool_index = 0;
    if(p_port_extender->type != SYS_EXTEND_QUE_TYPE_SERVICE || p_usw_queue_master[lchip]->service_queue_mode == 1 ||(p_port_extender->type == SYS_EXTEND_QUE_TYPE_SERVICE &&p_port_extender->dir == CTC_EGRESS &&p_port_extender->group_is_alloc&&p_port_extender->logic_dst_port))
    {
        CTC_ERROR_GOTO(sys_usw_opf_alloc_offset_from_position(lchip, &opf, opf_num, p_port_extender->key_index), ret, done);
    }
    }

    CTC_WB_QUERY_ENTRY_END(p_wb_query);
    }
    /* service logic src port */
    if (p_usw_queue_master[lchip]->p_service_hash)
    {
    CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_logicsrc_port_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_LOGIC_SRC_PORT);

    entry_cnt = 0;

    sal_memset(&wb_logicsrc_port, 0, sizeof(sys_wb_qos_logicsrc_port_t));
    p_wb_logicsrc_port = &wb_logicsrc_port;

    CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

    sal_memcpy((uint8 *)&wb_logicsrc_port, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                                        (p_wb_query->key_len + p_wb_query->data_len));
    entry_cnt++;
    sal_memset(&service, 0, sizeof(service));
    service.service_id = p_wb_logicsrc_port->service_id;
    p_service = sys_usw_service_lookup(lchip, &service);
    if (NULL == p_service)
    {
        p_service = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_service_node_t));
        if (NULL == p_service)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_service, 0, sizeof(sys_service_node_t));
        p_service->service_id = p_wb_logicsrc_port->service_id;
        p_service->p_logic_port_list = ctc_slist_new();
        if (p_service->p_logic_port_list == NULL)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        p_service->p_dest_port_list = ctc_slist_new();
        if (p_service->p_dest_port_list == NULL)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sys_usw_service_add(lchip, p_service);
    }

    if(p_wb_logicsrc_port->logic_src_port == 0)
    {
        continue;
    }
    p_logicsrc_port = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_logicport_t));
    if (NULL == p_logicsrc_port)
    {
        ret = CTC_E_NO_MEMORY;
        goto done;
    }
    sal_memset(p_logicsrc_port, 0, sizeof(sys_qos_logicport_t));
    p_logicsrc_port->logic_port = p_wb_logicsrc_port->logic_src_port;
    ctc_slist_add_tail(p_service->p_logic_port_list, &p_logicsrc_port->head);

    p_logicport_service = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_logicport_service_t));
    if (NULL == p_logicport_service)
    {
        ret = CTC_E_NO_MEMORY;
        goto done;
    }
    sal_memset(p_logicport_service, 0, sizeof(sys_qos_logicport_service_t));
    p_logicport_service->logic_src_port = p_wb_logicsrc_port->logic_src_port;
    p_logicport_service->service_id = p_wb_logicsrc_port->service_id;
    ctc_hash_insert(p_usw_queue_master[lchip]->p_logicport_service_hash, p_logicport_service);

    CTC_WB_QUERY_ENTRY_END(p_wb_query);
    }
    /* service dest port */
    if (p_usw_queue_master[lchip]->p_service_hash)
    {
    CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_destport_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_DESTPORT);

    entry_cnt = 0;

    sal_memset(&wb_dest_port, 0, sizeof(sys_wb_qos_destport_t));
    p_wb_dest_port = &wb_dest_port;

    CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

    sal_memcpy((uint8 *)&wb_dest_port, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                                        (p_wb_query->key_len + p_wb_query->data_len));
    entry_cnt++;
    sal_memset(&service, 0, sizeof(service));
    service.service_id = p_wb_dest_port->service_id;
    p_service = sys_usw_service_lookup(lchip, &service);
    if (NULL == p_service)
    {
        p_service = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_service_node_t));
        if (NULL == p_service)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sal_memset(p_service, 0, sizeof(sys_service_node_t));
        p_service->service_id = p_wb_dest_port->service_id;
        p_service->p_logic_port_list = ctc_slist_new();
        if (p_service->p_logic_port_list == NULL)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        p_service->p_dest_port_list = ctc_slist_new();
        if (p_service->p_dest_port_list == NULL)
        {
            ret = CTC_E_NO_MEMORY;
            goto done;
        }
        sys_usw_service_add(lchip, p_service);
    }

    p_dest_port = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_qos_destport_t));
    if (NULL == p_dest_port)
    {
        ret = CTC_E_NO_MEMORY;
        goto done;
    }

    p_dest_port->lchip = lchip;
    p_dest_port->lport = p_wb_dest_port->lport;
    ctc_slist_add_tail(p_service->p_dest_port_list, &p_dest_port->head);

    CTC_WB_QUERY_ENTRY_END(p_wb_query);
    }

    /* cpu reason */
    CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_cpu_reason_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_CPU_REASON);

    entry_cnt = 0;

    sal_memset(&wb_cpu_reason, 0, sizeof(sys_wb_qos_cpu_reason_t));
    p_wb_cpu_reason = &wb_cpu_reason;

    CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

    sal_memcpy((uint8 *)&wb_cpu_reason, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                                    (p_wb_query->key_len + p_wb_query->data_len));
    entry_cnt++;

    if (p_wb_cpu_reason->reason_id >= CTC_PKT_CPU_REASON_MAX_COUNT)
    {
        continue;
    }
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].dest_type = p_wb_cpu_reason->dest_type;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].user_define_mode[CTC_INGRESS] = p_wb_cpu_reason->user_define_mode0;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].user_define_mode[CTC_EGRESS] = p_wb_cpu_reason->user_define_mode1;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].excp_id[CTC_INGRESS] = p_wb_cpu_reason->excp_id0;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].excp_id[CTC_EGRESS] = p_wb_cpu_reason->excp_id1;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].nh_id = p_wb_cpu_reason->nh_id;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].sub_queue_id = p_wb_cpu_reason->sub_queue_id;
    //p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].ref_cnt = p_wb_cpu_reason->ref_cnt;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].dest_port = p_wb_cpu_reason->dest_port;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].dir = p_wb_cpu_reason->dir;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].policer_id[0] = p_wb_cpu_reason->policer_id[0];
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].policer_id[1] = p_wb_cpu_reason->policer_id[1];
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].tcat_prof_id = p_wb_cpu_reason->tcat_prof_id;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].raw_dest_en = p_wb_cpu_reason->raw_dest_en;
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].sub_idx = p_wb_cpu_reason->sub_index;

    if ((2 == p_wb_cpu_reason->user_define_mode0) && (0 != p_wb_cpu_reason->excp_id0))
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
        opf.pool_type = p_usw_queue_master[lchip]->opf_type_excp_index;
        opf.pool_index = CTC_INGRESS;
        CTC_ERROR_GOTO(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_wb_cpu_reason->excp_id0), ret, done);
        if (p_wb_cpu_reason->reason_id >= CTC_PKT_CPU_REASON_CUSTOM_BASE)
        {
            p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].is_uc = 0;
        }
    }
    if ((2 == p_wb_cpu_reason->user_define_mode1) && (0 != p_wb_cpu_reason->excp_id1))
    {
        sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
        opf.pool_type = p_usw_queue_master[lchip]->opf_type_excp_index;
        opf.pool_index = CTC_EGRESS;
        CTC_ERROR_GOTO(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, p_wb_cpu_reason->excp_id1), ret, done);
        if (p_wb_cpu_reason->reason_id >= CTC_PKT_CPU_REASON_CUSTOM_BASE)
        {
            p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].is_uc = 0;
        }
    }
    sal_memset(&dest_info, 0, sizeof(sys_cpu_reason_dest_info_t));
    dest_info.dest_type = p_wb_cpu_reason->dest_type;
    dest_info.sub_idx = p_wb_cpu_reason->sub_index;
    dest_info.dest_port = p_wb_cpu_reason->dest_port;
    CTC_ERROR_RETURN(_sys_usw_cpu_reason_encode_dest_info(lchip, p_wb_cpu_reason->reason_id, &dest_info));
    p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].dest_map = dest_info.dest_map;

    #if 0
    if(flag == 3 && p_wb_cpu_reason->reason_id < CTC_PKT_CPU_REASON_CUSTOM_BASE && p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].sub_queue_id != CTC_MAX_UINT16_VALUE)
    {
        drv_set_warmboot_status(lchip, CTC_WB_STATUS_DONE);
        sys_usw_cpu_reason_set_map(lchip,  p_wb_cpu_reason->reason_id, p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].sub_queue_id%MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM),
                       p_usw_queue_master[lchip]->cpu_reason[p_wb_cpu_reason->reason_id].sub_queue_id/MCHIP_CAP(SYS_CAP_REASON_GRP_QUEUE_NUM), 0);
        drv_set_warmboot_status(lchip, CTC_WB_STATUS_RELOADING);
    }
    #endif

    CTC_WB_QUERY_ENTRY_END(p_wb_query);

    if(DRV_FROM_TMM(lchip))
    {
        uint8 child_level = 0;
        uint8 parent_level = 0;
        uint32 sch_child_grp_id = 0;
        uint32 sub_child_grp_id = 0;
        uint32 sub_parent_grp_id = 0;
        uint32 grp_parent_vec_index = 0;

        /* queue sch group node */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_sch_group_node_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_SCH_GROUP_NODE);

        entry_cnt = 0;

        sal_memset(&wb_qos_queue_sch_group_node, 0, sizeof(sys_wb_qos_queue_sch_group_node_t));
        p_wb_qos_queue_sch_group_node = &wb_qos_queue_sch_group_node;

        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

        sal_memcpy((uint8 *)&wb_qos_queue_sch_group_node, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                   (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;

        p_sch_group_node = ctc_vector_get(p_usw_queue_master[lchip]->sch_group_vec, p_wb_qos_queue_sch_group_node->grp_index);
        if (NULL == p_sch_group_node)/*init has already create dma/bpe sch group*/
        {
            p_sch_group_node = mem_malloc(MEM_QUEUE_MODULE,  sizeof(sys_sch_group_node_t));
            if (NULL == p_sch_group_node)
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }

            sal_memset(p_sch_group_node, 0, sizeof(sys_sch_group_node_t));
            p_sch_group_node->grp_index = p_wb_qos_queue_sch_group_node->grp_index;
            p_sch_group_node->chan_id = p_wb_qos_queue_sch_group_node->chan_id;
            p_sch_group_node->chan_valid = p_wb_qos_queue_sch_group_node->chan_valid;
            p_sch_group_node->parent_id = p_wb_qos_queue_sch_group_node->parent_id;
            p_sch_group_node->p_child_list = ctc_slist_new();
            if (p_sch_group_node->p_child_list == NULL)
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }
            if (!ctc_vector_add(p_usw_queue_master[lchip]->sch_group_vec,
                                          p_sch_group_node->grp_index, p_sch_group_node))
            {
                ret = CTC_E_NO_MEMORY;
                goto done;
            }

            SYS_GRP_VEC_INDEX_TO_SUB_GRP(p_sch_group_node->grp_index, child_level, sub_child_grp_id);
            if(p_sch_group_node->parent_id && child_level != CTC_QOS_SCHED_GROUP_LVL_R)
            {
                SYS_LVL_GRP_TO_SUB_GRP(p_sch_group_node->parent_id, parent_level, sub_parent_grp_id);
                SYS_SUB_GRP_TO_GRP_VEC_INDEX(grp_parent_vec_index, parent_level, sub_parent_grp_id);
                p_sch_group_parent_node = ctc_vector_get(p_usw_queue_master[lchip]->sch_group_vec, grp_parent_vec_index);
                if (NULL == p_sch_group_parent_node)
                {
                    SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " Entry not exist \n");
                    ret = CTC_E_NOT_EXIST;
                    goto done;
                }

                p_sch_group_child = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_sch_group_child_node_t));
                if (NULL == p_sch_group_child)
                {
                    ret = CTC_E_NO_MEMORY;
                    goto done;
                }
                sal_memset(p_sch_group_child, 0, sizeof(sys_sch_group_child_node_t));
                SYS_SUB_GRP_TO_LVL_GRP(sch_child_grp_id, child_level, lchip, sub_child_grp_id)
                p_sch_group_child->child_id = sch_child_grp_id;

                ctc_slist_add_tail(p_sch_group_parent_node->p_child_list, &p_sch_group_child->head);
            }
            if(child_level != CTC_QOS_SCHED_GROUP_LVL_Q)
            {
                sal_memset(&opf, 0, sizeof(sys_usw_opf_t));
                opf.pool_type = p_usw_queue_master[lchip]->opf_type_sch_group;
                opf.pool_index = child_level;
                CTC_ERROR_GOTO(sys_usw_opf_alloc_offset_from_position(lchip, &opf, 1, sub_child_grp_id), ret, done);
            }
        }
        CTC_WB_QUERY_ENTRY_END(p_wb_query);

        /* cpu reason */
        CTC_WB_INIT_QUERY_T(p_wb_query, sys_wb_qos_queue_fcdl_t, CTC_FEATURE_QOS, SYS_WB_APPID_QOS_SUBID_QUEUE_FCDL);

        entry_cnt = 0;

        sal_memset(&wb_queue_fcdl, 0, sizeof(sys_wb_qos_queue_fcdl_t));
        p_wb_queue_fcdl = &wb_queue_fcdl;

        CTC_WB_QUERY_ENTRY_BEGIN(p_wb_query);

        sal_memcpy((uint8 *)&wb_queue_fcdl, (uint8 *)p_wb_query->buffer + entry_cnt * (p_wb_query->key_len + p_wb_query->data_len),
                                        (p_wb_query->key_len + p_wb_query->data_len));
        entry_cnt++;

        p_usw_queue_master[lchip]->fcdl_info[p_wb_queue_fcdl->lport].mode = p_wb_queue_fcdl->mode;
        p_usw_queue_master[lchip]->fcdl_info[p_wb_queue_fcdl->lport].timeout = p_wb_queue_fcdl->timeout;
        /*first enable should start timer*/
        if((p_wb_queue_fcdl->mode == 2) && p_wb_queue_fcdl->timeout && !p_usw_queue_master[lchip]->p_recover_timer)
        {
            sys_usw_qos_fcdl_timer_en(lchip,TRUE);
        }

        CTC_WB_QUERY_ENTRY_END(p_wb_query);
    }
done:
    mem_free(p_wb_qos_queue_master);
    return ret;
}

int32
_sys_usw_qos_queue_bind_cpu_reason(uint8 lchip, uint16 reason_id)
{
    p_usw_queue_master[lchip]->cpu_reason[reason_id].ref_cnt++;
    return CTC_E_NONE;
}

int32
sys_usw_qos_queue_dump_db(uint8 lchip, sal_file_t dump_db_fp,ctc_global_dump_db_t* p_dump_param)
{
    sys_dump_db_traverse_param_t    cb_data;
    uint32 num_cnt = 1;
    uint32 mode = 0;
    uint16 i = 0;
    uint8 j = 0;
    uint8 count = 0;
    sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));

    SYS_DUMP_DB_LOG(dump_db_fp, "\n");
    SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "##Queue");
    SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "Master config:");
    SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------------------");

    if(!DRV_FROM_TMM(lchip))
    {
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:","p_fc_profile");
        for(i = 0; i < MCHIP_CAP(SYS_CAP_CHANNEL_NUM); i ++)
        {
            if(p_usw_queue_master[lchip]->p_fc_profile[i]&&p_usw_queue_master[lchip]->p_fc_profile[i]->xon == 224&&p_usw_queue_master[lchip]->p_fc_profile[i]->xoff == 256&&p_usw_queue_master[lchip]->p_fc_profile[i]->thrd == 0 &&
                p_usw_queue_master[lchip]->p_fc_profile[i]->profile_id == 0&&p_usw_queue_master[lchip]->p_fc_profile[i]->type == 0)
            {
                continue;
            }
            if(p_usw_queue_master[lchip]->p_fc_profile[i])
            {
                count ++;
                SYS_DUMP_DB_LOG(dump_db_fp,"[%u:%u,%u,%u,%u,%u]",i,p_usw_queue_master[lchip]->p_fc_profile[i]->xon,p_usw_queue_master[lchip]->p_fc_profile[i]->xoff,p_usw_queue_master[lchip]->p_fc_profile[i]->thrd,
                p_usw_queue_master[lchip]->p_fc_profile[i]->profile_id,p_usw_queue_master[lchip]->p_fc_profile[i]->type);
            }
            if(count%4 == 3 && p_usw_queue_master[lchip]->p_fc_profile[i])
            {
                SYS_DUMP_DB_LOG(dump_db_fp, "\n%31s"," ");
            }
        }
        SYS_DUMP_DB_LOG(dump_db_fp, "\n");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:","p_pfc_profile");
        count = 0;
        for(i = 0; i < MCHIP_CAP(SYS_CAP_CHANNEL_NUM); i ++)
        {
            for(j = 0; j < 8; j ++)
            {
                if(p_usw_queue_master[lchip]->p_pfc_profile[i][j]&&p_usw_queue_master[lchip]->p_pfc_profile[i][j]->xon == 224&&p_usw_queue_master[lchip]->p_pfc_profile[i][j]->xoff == 256&&p_usw_queue_master[lchip]->p_pfc_profile[i][j]->thrd == 0 &&
                    p_usw_queue_master[lchip]->p_pfc_profile[i][j]->profile_id == 0&&p_usw_queue_master[lchip]->p_pfc_profile[i][j]->type == 0)
                {
                    continue;
                }
                if(p_usw_queue_master[lchip]->p_pfc_profile[i][j])
                {
                    count ++;
                    SYS_DUMP_DB_LOG(dump_db_fp,"[%u-%u:%u,%u,%u,%u,%u]",i,j,p_usw_queue_master[lchip]->p_pfc_profile[i][j]->xon,p_usw_queue_master[lchip]->p_pfc_profile[i][j]->xoff,p_usw_queue_master[lchip]->p_pfc_profile[i][j]->thrd,
                    p_usw_queue_master[lchip]->p_pfc_profile[i][j]->profile_id,p_usw_queue_master[lchip]->p_pfc_profile[i][j]->type);
                }
                if(count%4 == 3 && p_usw_queue_master[lchip]->p_pfc_profile[i][j])
                {
                    SYS_DUMP_DB_LOG(dump_db_fp, "\n%31s"," ");
                }
            }
        }
        SYS_DUMP_DB_LOG(dump_db_fp, "\n");

        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","store_chan_shp_en",p_usw_queue_master[lchip]->store_chan_shp_en);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","store_que_shp_en",p_usw_queue_master[lchip]->store_que_shp_en);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","have_lcpu_by_eth",p_usw_queue_master[lchip]->have_lcpu_by_eth);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","cpu_eth_chan_id",p_usw_queue_master[lchip]->cpu_eth_chan_id);
    }

    if(DRV_FROM_AT(lchip))
    {
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n", "igs_uc_resrc_mode", p_usw_queue_master[lchip]->igs_resrc_mode[0]);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n", "egs_uc_resrc_mode", p_usw_queue_master[lchip]->egs_resrc_mode[0]);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n", "igs_mc_resrc_mode", p_usw_queue_master[lchip]->igs_resrc_mode[1]);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n", "egs_mc_resrc_mode", p_usw_queue_master[lchip]->egs_resrc_mode[1]);
    }
    else
    {
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","igs_resrc_mode",p_usw_queue_master[lchip]->igs_resrc_mode[0]);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","egs_resrc_mode",p_usw_queue_master[lchip]->egs_resrc_mode[0]);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","service_queue_mode",p_usw_queue_master[lchip]->service_queue_mode);
    }

    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","enq_mode",p_usw_queue_master[lchip]->enq_mode);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","monitor_drop_en",p_usw_queue_master[lchip]->monitor_drop_en);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","shp_pps_en",p_usw_queue_master[lchip]->shp_pps_en);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","net_shp_pps_en",p_usw_queue_master[lchip]->net_shp_pps_en);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","queue_num_per_chanel",p_usw_queue_master[lchip]->queue_num_per_chanel);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","queue_num_per_extend_port",p_usw_queue_master[lchip]->queue_num_per_extend_port);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","max_dma_rx_num",p_usw_queue_master[lchip]->max_dma_rx_num);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","chan_shp_update_freq",p_usw_queue_master[lchip]->chan_shp_update_freq);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","que_shp_update_freq",p_usw_queue_master[lchip]->que_shp_update_freq);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:","que_shp_gran");
    for(i = 0; i < SYS_SHP_GRAN_RANAGE_NUM; i ++)
    {
        SYS_DUMP_DB_LOG(dump_db_fp, "[%u,%u]",p_usw_queue_master[lchip]->que_shp_gran[i].max_rate,p_usw_queue_master[lchip]->que_shp_gran[i].granularity);
    }
    SYS_DUMP_DB_LOG(dump_db_fp, "\n");
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","queue_num_for_cpu_reason",p_usw_queue_master[lchip]->queue_num_for_cpu_reason);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_group_id",p_usw_queue_master[lchip]->opf_type_group_id);

    if(!DRV_FROM_TMM(lchip))
    {
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_tcam_index",p_usw_queue_master[lchip]->opf_type_tcam_index);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_queue_shape",p_usw_queue_master[lchip]->opf_type_queue_shape);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_queue_meter",p_usw_queue_master[lchip]->opf_type_queue_meter);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_group_shape",p_usw_queue_master[lchip]->opf_type_group_shape);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_group_meter",p_usw_queue_master[lchip]->opf_type_group_meter);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_queue_drop_wtd",p_usw_queue_master[lchip]->opf_type_queue_drop_wtd);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_resrc_fc",p_usw_queue_master[lchip]->opf_type_resrc_fc);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_resrc_pfc",p_usw_queue_master[lchip]->opf_type_resrc_pfc);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_queue_guarantee",p_usw_queue_master[lchip]->opf_type_queue_guarantee);
    }
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_excp_index",p_usw_queue_master[lchip]->opf_type_excp_index);
    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_queue_drop_wred",p_usw_queue_master[lchip]->opf_type_queue_drop_wred);

    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:","egs_pool");
    for(i = 0; i < CTC_QOS_EGS_RESRC_POOL_MAX; i ++)
    {
        SYS_DUMP_DB_LOG(dump_db_fp, "[%u,%u]",p_usw_queue_master[lchip]->egs_pool[i].egs_congest_level_num,p_usw_queue_master[lchip]->egs_pool[i].default_profile_id);
    }
    SYS_DUMP_DB_LOG(dump_db_fp, "\n");

    if(!DRV_FROM_TMM(lchip))
    {
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_resrc_fc_dropthrd",p_usw_queue_master[lchip]->opf_type_resrc_fc_dropthrd);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","opf_type_resrc_pfc_dropthrd",p_usw_queue_master[lchip]->opf_type_resrc_pfc_dropthrd);
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:","p_dropthrd_fc_profile");
        count = 0;
        for(i = 0; i < MCHIP_CAP(SYS_CAP_CHANNEL_NUM); i ++)
        {
            if(p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i])
            {
                count ++;
                SYS_DUMP_DB_LOG(dump_db_fp,"[%u:%u,%u,%u,%u,%u]",i,p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i]->xon,p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i]->xoff,p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i]->thrd,
                p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i]->profile_id,p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i]->type);
            }
            if(count%4 == 3 && p_usw_queue_master[lchip]->p_dropthrd_fc_profile[i])
            {
                SYS_DUMP_DB_LOG(dump_db_fp, "\n%31s"," ");
            }
        }
        SYS_DUMP_DB_LOG(dump_db_fp, "\n");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:","p_dropthrd_pfc_profile");
        count = 0;
        for(i = 0; i < MCHIP_CAP(SYS_CAP_CHANNEL_NUM); i ++)
        {
            for(j = 0; j < 8; j ++)
            {
                if(p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j])
                {
                    count ++;
                    SYS_DUMP_DB_LOG(dump_db_fp,"[%u-%u:%u,%u,%u,%u,%u]",i,j,p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j]->xon,p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j]->xoff,p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j]->thrd,
                    p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j]->profile_id,p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j]->type);
                }
                if(count%4 == 3 && p_usw_queue_master[lchip]->p_dropthrd_pfc_profile[i][j])
                {
                    SYS_DUMP_DB_LOG(dump_db_fp, "\n%31s"," ");
                }
            }
        }
        SYS_DUMP_DB_LOG(dump_db_fp, "\n");
    }

    SYS_DUMP_DB_LOG(dump_db_fp, "%-30s:%u\n","resrc_check_mode",p_usw_queue_master[lchip]->resrc_check_mode);
    SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------------------");
    SYS_DUMP_DB_LOG(dump_db_fp, "\n");

    if(!DRV_FROM_AT(lchip))
    {
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_group_id, dump_db_fp);
    }
    sys_usw_opf_fprint_alloc_used_info(drv_vchip_get_pp_base(lchip), p_usw_queue_master[lchip]->opf_type_excp_index, dump_db_fp);
    if(DRV_FROM_TMM(lchip))
    {
        sys_usw_opf_fprint_alloc_used_info(drv_vchip_get_pp_base(lchip), p_usw_queue_master[lchip]->opf_type_queue_drop_wred, dump_db_fp);
        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_DROP_WRED_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_drop_wred_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-5s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-8s%-6s\n","Node","min_td3","min_td2","min_td1","min_td0","max_td3","max_td2","max_td1",
                         "max_td0","factor0","factor1","factor2","factor3","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_drop_wred_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");

    }
    else
    {
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_tcam_index, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_queue_shape, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_queue_meter, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_group_shape, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_group_meter, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wtd, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_queue_drop_wred, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_resrc_fc, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_resrc_pfc, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_resrc_fc_dropthrd, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_resrc_pfc_dropthrd, dump_db_fp);
        sys_usw_opf_fprint_alloc_used_info(lchip, p_usw_queue_master[lchip]->opf_type_queue_guarantee, dump_db_fp);
        SYS_DUMP_DB_LOG(dump_db_fp, "\n");
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_queue_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-15s%-15s%-15s%-7s\n","Node","queue_type","bucket_thrd","bucket_rate","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------");
        cb_data.value0 = dump_db_fp;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_queue_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_METER_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_queue_meter_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-15s%-15s%-7s\n","Node","bucket_thrd","bucket_rate","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_queue_meter_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_DROP_WTD_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_drop_wtd_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-5s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-8s%-6s\n","Node","ecn_td0","ecn_td1","ecn_td2","ecn_td3","wtd_td3","wtd_td2","wtd_td1",
                         "wtd_td0","factor3","factor2","factor1","factor0","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_drop_wtd_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_DROP_WRED_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_drop_wred_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-5s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-9s%-8s%-6s\n","Node","min_td3","min_td2","min_td1","min_td0","max_td3","max_td2","max_td1",
                         "max_td0","factor0","factor1","factor2","factor3","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_drop_wred_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_GROUP_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_group_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-15s%-15s%-7s\n","Node","bucket_thrd","bucket_rate","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_group_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_GROUP_METER_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_group_profile_meter_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_group_profile_meter_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_FC_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_fc_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-7s%-7s%-7s%-7s\n","Node","xon","xoff","thrd","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_fc_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_PFC_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_pfc_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-7s%-7s%-7s%-7s\n","Node","xon","xoff","thrd","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_pfc_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_FC_DROP_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_fc_dropthrd_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-7s%-7s%-7s%-7s\n","Node","xon","xoff","thrd","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_fc_dropthrd_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_PFC_DROP_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_pfc_dropthrd_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-7s%-7s%-7s%-7s\n","Node","xon","xoff","thrd","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_pfc_dropthrd_profile_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");

        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_MIN_PROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_queue_guarantee_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-7s%-7s%-7s\n","Node","thrd","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->p_queue_guarantee_pool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "---------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "}");
    }

    if (DRV_FROM_AT(lchip))
    {
        sal_memset(&cb_data, 0, sizeof(sys_dump_db_traverse_param_t));
        cb_data.value0 = dump_db_fp;
        num_cnt = 1;
        cb_data.value1 = &num_cnt;
        mode = SYS_QUEUE_ENQ_FROFILE;
        cb_data.value2 = &mode;
        cb_data.lchip = lchip;
        SYS_DUMP_DB_LOG(dump_db_fp, "Spool type: %s\n","p_queue_enq_profile_pool");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%-5s%-11s%-14s%-13s%-12s%-12s%-18s%-11s%-17s%-12s%s\n","Node","is_mc","UC","MC","SPAN","CPU_PKT","CPU_PKT_PRIO","C2C","UNKNOWN_MC","OAM","refcnt");
        SYS_DUMP_DB_LOG(dump_db_fp, "            %-5s%-9s%-5s%-9s%-5s%-9s%-5s%-9s%-5s%-9s%-5s%-9s%-5s%-9s%-5s%-9s\n","mode","offset","mode","offset","mode","offset","mode"
        ,"offset","mode","offset","mode","offset","mode","offset","mode","offset");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------------------------------------------");
        ctc_spool_traverse(p_usw_queue_master[lchip]->enq_prof_spool, (spool_traversal_fn)_sys_usw_qos_queue_traverse_fprintf_pool , (void*)(&cb_data));
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "----------------------------------------------------------------------------------------------------------------------------------------------");
        SYS_DUMP_DB_LOG(dump_db_fp, "%s\n", "}");
    }

    return CTC_E_NONE;
}

/**
 @brief En-queue component initialization.
*/
int32
sys_usw_queue_enq_init(uint8 lchip, void *p_glb_parm)
{
    int32 ret = CTC_E_NONE;
    uint8 gchip = 0;
    uint16 lport = 0;
#if (SDK_WORK_PLATFORM == 0) && (0 == SDK_WORK_ENV)
    uint32 port_type = 0;
#endif
    uint16 loop = 0;
    uint32 channel = 0;
    uint32 field_val = 0;
    uint32 cmd = 0;
    uint16 group_num = 0;
    sys_queue_node_t  *p_queue_node = NULL;
    sys_queue_group_node_t *p_sys_group_node = NULL;
    sys_usw_opf_t  opf;
    ctc_qos_global_cfg_t * p_glb_cfg = NULL;
    uint16 chan_num = 0;
    uint32 max_size = 0;
    uint32 loop_queue_end = 0;
    sys_usw_dmps_port_info_t dmps_port_info = {0};
    p_glb_cfg = (ctc_qos_global_cfg_t *)p_glb_parm;

    if (NULL != p_usw_queue_master[lchip])
    {
        return CTC_E_NONE;
    }

    /*check queue mode*/
    if ((CTC_QOS_PORT_QUEUE_NUM_8 != p_glb_cfg->queue_num_per_network_port)
        && (CTC_QOS_PORT_QUEUE_NUM_16 != p_glb_cfg->queue_num_per_network_port)
        && (CTC_QOS_PORT_QUEUE_NUM_16_2 != p_glb_cfg->queue_num_per_network_port))
    {
        return CTC_E_INVALID_PARAM;
    }

    if ((128 != p_glb_cfg->queue_num_for_cpu_reason)
        && (64 != p_glb_cfg->queue_num_for_cpu_reason)
        && (32 != p_glb_cfg->queue_num_for_cpu_reason))
    {
        return CTC_E_INVALID_PARAM;
    }

    if (p_glb_cfg->queue_num_per_internal_port)
    {
        p_glb_cfg->queue_num_per_internal_port = MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
    }

    p_usw_queue_master[lchip] = mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_queue_master_t));
    if (NULL == p_usw_queue_master[lchip])
    {
        SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
        ret = CTC_E_NO_MEMORY;
        goto error0;
    }
    sal_memset(p_usw_queue_master[lchip], 0, sizeof(sys_queue_master_t));
    CTC_MAX_VALUE_CHECK(p_glb_cfg->service_queue_mode,1);
    p_usw_queue_master[lchip]->service_queue_mode = p_glb_cfg->service_queue_mode;

    field_val = !!p_usw_queue_master[lchip]->service_queue_mode;
    cmd = DRV_IOW(QWriteCtl_t, QWriteCtl_useNextHopPtr_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val));

    p_usw_queue_master[lchip]->queue_num_per_stk_port = (DRV_FROM_TMM(lchip) && p_glb_cfg->queue_num_per_stk_port) ? 1 : 0;
    if (CTC_QOS_PORT_QUEUE_NUM_16 == p_glb_cfg->queue_num_per_network_port)
    {
        p_usw_queue_master[lchip]->queue_num_per_chanel = DRV_IS_DUET2(lchip) ? 14 :11;
        p_usw_queue_master[lchip]->enq_mode = 1;
    }
    else if(CTC_QOS_PORT_QUEUE_NUM_16_2 == p_glb_cfg->queue_num_per_network_port)
    {
        p_usw_queue_master[lchip]->queue_num_per_chanel = 10;
        p_usw_queue_master[lchip]->enq_mode = 2;
    }
    else
    {
        p_usw_queue_master[lchip]->queue_num_per_chanel = 9;
        p_usw_queue_master[lchip]->enq_mode = 0;
    }
    if(DRV_FROM_TMM(lchip) && p_glb_cfg->queue_num_per_stk_port)
    {
        p_usw_queue_master[lchip]->queue_num_per_stk_port = 1;
        p_usw_queue_master[lchip]->queue_num_per_chanel += 1; /*add c2c ctl queue*/
    }
        
    p_usw_queue_master[lchip]->oobfc_group_info.mode = CTC_QOS_OOBFC_MODE_MAX;
    /*queue num, D2:1280; TM:4096; TMM:12288*/
    if (DRV_IS_DUET2(lchip))
    {
        p_usw_queue_master[lchip]->queue_vec = ctc_vector_init(80, 16);
    }
    else if(DRV_IS_TSINGMA(lchip))
    {
        p_usw_queue_master[lchip]->queue_vec = ctc_vector_init(128, 32);
    }
    else if(DRV_IS_TMG(lchip))
    {
        p_usw_queue_master[lchip]->queue_vec = ctc_vector_init(80, 32);
    }
    else if(DRV_FROM_TMM(lchip))
    {
        p_usw_queue_master[lchip]->queue_vec = ctc_vector_init(192, 64);
    }

    if (NULL == p_usw_queue_master[lchip]->queue_vec)
    {
        ret = CTC_E_NO_MEMORY;
        goto error1;
    }

    loop_queue_end = MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM);
    for (loop = 0; loop < loop_queue_end; loop++)
    {
        p_queue_node = (sys_queue_node_t*)mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_queue_node_t));
        if (!p_queue_node)
        {
            SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
            ret = CTC_E_NO_MEMORY;
            goto error2;
        }

        sal_memset(p_queue_node, 0, sizeof(sys_queue_node_t));
        p_queue_node->queue_id = loop;
        p_queue_node->node[0].drop_wred_profile_id = DRV_FROM_TMM(lchip) ? 0 : MCHIP_CAP(SYS_CAP_QOS_QUEUE_DROP_WRED_PROFILE_NUM);
        /*tm:[0~768),tmm:[0~11264)*/
        if(loop < MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC))
        {
            p_queue_node->offset = loop % MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_GRP);
        }
        /*tm:[768~1024),tmm:[11264~12288)*/
        else if(loop >= MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_NETWORK_MISC) &&
                loop < (DRV_FROM_TMM(lchip) ? MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM) : MCHIP_CAP(SYS_CAP_QOS_QUEUE_BASE_EXT)))
        {
            p_queue_node->offset = loop % MCHIP_CAP(SYS_CAP_QOS_CTL_QUEUE_NUM);
        }
        /*tm:[1024~4096)*/
        else
        {
            p_queue_node->offset = loop % MCHIP_CAP(SYS_CAP_QOS_QUEUE_NUM_PER_EXT_GRP);
        }
        (void)ctc_vector_add(p_usw_queue_master[lchip]->queue_vec, loop, p_queue_node);
    }

    if (!DRV_FROM_TMM(lchip))
    {
        /*64 ext group*/
        p_usw_queue_master[lchip]->group_vec = ctc_vector_init(1, MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM));
        if (NULL == p_usw_queue_master[lchip]->group_vec)
        {
            ret = CTC_E_NO_MEMORY;
            goto error2;
        }

        for (loop = 0; loop < MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM); loop++)
        {
            p_sys_group_node = (sys_queue_group_node_t*)mem_malloc(MEM_QUEUE_MODULE, sizeof(sys_queue_group_node_t));
            if (!p_sys_group_node)
            {
                SYS_QOS_QUEUE_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " No memory \n");
                ret = CTC_E_NO_MEMORY;
                goto error3;
            }

            sal_memset(p_sys_group_node, 0, sizeof(sys_queue_group_node_t));
            p_sys_group_node->group_id = loop;
            p_sys_group_node->chan_id = 0xFF;
            (void)ctc_vector_add(p_usw_queue_master[lchip]->group_vec, loop, p_sys_group_node);
        }
    }


    p_usw_queue_master[lchip]->p_port_extender_hash = ctc_hash_create(
                                                  SYS_SERVICE_HASH_BLOCK_NUM,
                                                  SYS_SERVICE_HASH_BLOCK_SIZE,
                                                  (hash_key_fn)sys_usw_port_extender_hash_make,
                                                  (hash_cmp_fn)sys_usw_port_extender_hash_cmp);
    if (NULL == p_usw_queue_master[lchip]->p_port_extender_hash)
    {
        ret = CTC_E_NO_MEMORY;
        goto error3;
    }

    CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_group_id,
                                                                    1, "opf-queue-group-id"), ret, error4);
    opf.pool_index = 0;
    opf.pool_type  = p_usw_queue_master[lchip]->opf_type_group_id;
    if (DRV_FROM_TM(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM)-1), ret, error5);
    }
    else
    {
        /* D2 enq_mode == 1 not support span on drop*/
        group_num = p_usw_queue_master[lchip]->enq_mode == 1 ? MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM) : MCHIP_CAP(SYS_CAP_QOS_EXT_QUEUE_GRP_NUM)-1;
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, group_num), ret, error5);
    }

    if (!DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_opf_init(lchip, &p_usw_queue_master[lchip]->opf_type_tcam_index,
                                        1, "opf-queue-tcam-index"), ret, error5);

        opf.pool_index = 0;
        opf.pool_type  = p_usw_queue_master[lchip]->opf_type_tcam_index;
        sys_usw_ftm_query_table_entry_num(lchip, DsQueueMapTcamKey_t, &max_size);
        CTC_ERROR_GOTO(sys_usw_opf_init_offset(lchip, &opf, 0, max_size), ret, error6);
    }

    /*************************************************
    *init queue stats base
    *************************************************/
    field_val = 0;
    cmd = DRV_IOW(QWriteCtl_t, QWriteCtl_queStatsEn_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val), ret, error6);

    cmd = DRV_IOW(GlobalStatsUpdateEnCtl_t, GlobalStatsUpdateEnCtl_qMgrGlobalStatsUpdateEn_f);
    CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, 0, cmd, &field_val), ret, error6);

    sys_usw_dma_get_packet_rx_chan(lchip, &chan_num);
    p_usw_queue_master[lchip]->max_dma_rx_num = chan_num;  /* must get from DMA module */
    MCHIP_CAP(SYS_CAP_CHANID_DMA_NUM) = chan_num; /*DMA channel num*/

    if(!DRV_FROM_TMM(lchip))
    {
        CTC_ERROR_GOTO(sys_usw_queue_init_qmgr(lchip), ret, error6);
    }
   /*************************************************
    *init queue alloc */
    CTC_ERROR_GOTO(sys_usw_get_gchip_id(lchip, &gchip), ret, error6);

    for (lport = 0; lport < MCHIP_CAP(SYS_CAP_PORT_NUM); lport++)
    {
        dmps_port_info.gport = CTC_MAP_LPORT_TO_GPORT(gchip, lport);
#if (SDK_WORK_PLATFORM == 0) && (0 == SDK_WORK_ENV)
        CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_PORT_TYPE, (void *)&port_type), ret, error6);
        if (SYS_DMPS_RSV_PORT == port_type)
        {
            channel = MCHIP_CAP(SYS_CAP_CHANID_DROP);
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel));
        }
        if(DRV_IS_DUET2(lchip) && SYS_DMPS_NETWORK_PORT == port_type &&  p_usw_queue_master[lchip]->enq_mode == 1)
        {
            CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel), ret, error6);
            CTC_ERROR_GOTO(_sys_usw_qos_add_mcast_queue_to_channel(lchip, lport, channel, 0), ret, error6);
        }
#else
        if (lport < SYS_RSV_PORT_START)
        {
            channel = lport;
        }
        else
        {
            CTC_ERROR_RETURN(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel));
        }
        if(DRV_IS_DUET2(lchip) && lport < 40 &&  p_usw_queue_master[lchip]->enq_mode == 1)
        {
            CTC_ERROR_GOTO(sys_usw_port_api_get_dmps_property(lchip, &dmps_port_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &channel), ret, error6);
            CTC_ERROR_GOTO(_sys_usw_qos_add_mcast_queue_to_channel(lchip, lport, channel, 0), ret, error6);
        }
#endif
        CTC_ERROR_GOTO(_sys_usw_add_port_to_channel(lchip, lport, channel, 0), ret, error6);
    }

    p_usw_queue_master[lchip]->queue_num_per_extend_port = p_glb_cfg->queue_num_per_internal_port;
    if (!DRV_FROM_TMM(lchip))
    {
    if (0 == p_usw_queue_master[lchip]->enq_mode)
    {
        /*only use from cpu queue of ctl que*/
        field_val = 0xB;
        for (lport = 0; lport < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM); lport++)
        {
            cmd = DRV_IOW(QWriteNetChannel_t, QWriteNetChannel_miscQueueDisable_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, lport, cmd, &field_val), ret, error6);
        }
    }
    else if(1 == p_usw_queue_master[lchip]->enq_mode && DRV_FROM_TM(lchip))
    {
        /*only use cpu/mcast/log que*/
        field_val = 0x8;
        for (lport = 0; lport < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM); lport++)
        {
            cmd = DRV_IOW(QWriteNetChannel_t, QWriteNetChannel_miscQueueDisable_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, lport, cmd, &field_val), ret, error6);
        }
    }
    else if((1 == p_usw_queue_master[lchip]->enq_mode && DRV_IS_DUET2(lchip))
        || 2 == p_usw_queue_master[lchip]->enq_mode)
    {
        /*only use cpu/log que*/
        field_val = 0xA;
        for (lport = 0; lport < MCHIP_CAP(SYS_CAP_NETWORK_CHANNEL_NUM); lport++)
        {
            cmd = DRV_IOW(QWriteNetChannel_t, QWriteNetChannel_miscQueueDisable_f);
            CTC_ERROR_GOTO(DRV_FIELD_IOCTL(lchip, lport, cmd, &field_val), ret, error6);
        }
    }
    }
    p_usw_queue_master[lchip]->queue_num_for_cpu_reason = p_glb_cfg->queue_num_for_cpu_reason;
    if ((chan_num == 1) && (p_glb_cfg->queue_num_for_cpu_reason > 64))
    {
        p_usw_queue_master[lchip]->queue_num_for_cpu_reason = DRV_FROM_TMM(lchip)
                                                              ? p_glb_cfg->queue_num_for_cpu_reason : 64;
    }
    MCHIP_CAP(SYS_CAP_REASON_TOTAL_QUEUE_NUM) = p_usw_queue_master[lchip]->queue_num_for_cpu_reason;
    CTC_ERROR_GOTO(sys_usw_get_chip_cpu_eth_en(lchip, &p_usw_queue_master[lchip]->have_lcpu_by_eth,
                                                        &p_usw_queue_master[lchip]->cpu_eth_chan_id), ret, error6);
    if (!DRV_FROM_TMM(lchip) && p_usw_queue_master[lchip]->have_lcpu_by_eth)
    {
        CTC_ERROR_GOTO(sys_usw_chip_set_eth_cpu_cfg(lchip), ret, error6);
    }

    if (DRV_FROM_TMM(lchip) && MCHIP_QOS(lchip)->qos_que_init)
    {
        CTC_ERROR_GOTO(MCHIP_QOS(lchip)->qos_que_init(lchip), ret, error6);
    }

    p_usw_queue_master[lchip]->p_service_hash =
    ctc_hash_create(
            SYS_SERVICE_HASH_BLOCK_NUM,
            SYS_SERVICE_HASH_BLOCK_SIZE,
            (hash_key_fn)sys_usw_service_hash_make,
            (hash_cmp_fn)sys_usw_service_hash_cmp);
    if (NULL == p_usw_queue_master[lchip]->p_service_hash)
    {
        ret = CTC_E_NO_MEMORY;
        goto error6;
    }

    p_usw_queue_master[lchip]->p_logicport_service_hash =
    ctc_hash_create(
            SYS_SERVICE_HASH_BLOCK_NUM,
            SYS_SERVICE_HASH_BLOCK_SIZE,
            (hash_key_fn)sys_usw_logicport_service_hash_make,
            (hash_cmp_fn)sys_usw_logicport_service_hash_cmp);
    if (NULL == p_usw_queue_master[lchip]->p_logicport_service_hash)
    {
        ret = CTC_E_NO_MEMORY;
        goto error7;
    }

    return CTC_E_NONE;
error7:
    ctc_hash_free2(p_usw_queue_master[lchip]->p_service_hash, (hash_traversal_fn)_sys_usw_queue_hash_free_node_data, NULL);
error6:
    if (!DRV_FROM_TMM(lchip))
    {
        sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_tcam_index);
    }
error5:
    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_group_id);
error4:
    ctc_hash_free2(p_usw_queue_master[lchip]->p_port_extender_hash, (hash_traversal_fn)_sys_usw_queue_hash_free_node_data, NULL);
error3:
    ctc_vector_traverse(p_usw_queue_master[lchip]->group_vec, (vector_traversal_fn)_sys_usw_queue_vec_free_node_data, NULL);
    ctc_vector_release(p_usw_queue_master[lchip]->group_vec);
error2:
    ctc_vector_traverse(p_usw_queue_master[lchip]->queue_vec, (vector_traversal_fn)_sys_usw_queue_vec_free_node_data, NULL);
    ctc_vector_release(p_usw_queue_master[lchip]->queue_vec);
error1:
    mem_free(p_usw_queue_master[lchip]);
error0:
    return ret;
}

int32
sys_usw_queue_enq_deinit(uint8 lchip)
{
    if (NULL == p_usw_queue_master[lchip])
    {
        return CTC_E_NONE;
    }

    if (!DRV_FROM_TMM(lchip))
    {
        sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_tcam_index);
    }

    sys_usw_opf_deinit(lchip, p_usw_queue_master[lchip]->opf_type_group_id);

    ctc_hash_free2(p_usw_queue_master[lchip]->p_port_extender_hash, (hash_traversal_fn)_sys_usw_queue_hash_free_node_data, NULL);

    ctc_vector_traverse(p_usw_queue_master[lchip]->group_vec, (vector_traversal_fn)_sys_usw_queue_vec_free_node_data, NULL);
    ctc_vector_release(p_usw_queue_master[lchip]->group_vec);

    ctc_vector_traverse(p_usw_queue_master[lchip]->queue_vec, (vector_traversal_fn)_sys_usw_queue_vec_free_node_data, NULL);
    ctc_vector_release(p_usw_queue_master[lchip]->queue_vec);

    ctc_hash_free2(p_usw_queue_master[lchip]->p_service_hash, (vector_traversal_fn)_sys_usw_queue_hash_free_list_node_data, NULL);

    ctc_hash_free2(p_usw_queue_master[lchip]->p_logicport_service_hash, (vector_traversal_fn)_sys_usw_queue_hash_free_node_data, NULL);

    mem_free(p_usw_queue_master[lchip]);

    return CTC_E_NONE;
}

